{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #3Sum"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Medium"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #array #two-pointers #sorting"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #数组 #双指针 #排序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: threeSum"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #三数之和"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给你一个整数数组 <code>nums</code> ，判断是否存在三元组 <code>[nums[i], nums[j], nums[k]]</code> 满足 <code>i != j</code>、<code>i != k</code> 且 <code>j != k</code> ，同时还满足 <code>nums[i] + nums[j] + nums[k] == 0</code> 。请</p>\n",
    "\n",
    "<p>你返回所有和为 <code>0</code> 且不重复的三元组。</p>\n",
    "\n",
    "<p><strong>注意：</strong>答案中不可以包含重复的三元组。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [-1,0,1,2,-1,-4]\n",
    "<strong>输出：</strong>[[-1,-1,2],[-1,0,1]]\n",
    "<strong>解释：</strong>\n",
    "nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。\n",
    "nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。\n",
    "nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。\n",
    "不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。\n",
    "注意，输出的顺序和三元组的顺序并不重要。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [0,1,1]\n",
    "<strong>输出：</strong>[]\n",
    "<strong>解释：</strong>唯一可能的三元组和不为 0 。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>nums = [0,0,0]\n",
    "<strong>输出：</strong>[[0,0,0]]\n",
    "<strong>解释：</strong>唯一可能的三元组和为 0 。\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>3 &lt;= nums.length &lt;= 3000</code></li>\n",
    "\t<li><code>-10<sup>5</sup> &lt;= nums[i] &lt;= 10<sup>5</sup></code></li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [3sum](https://leetcode.cn/problems/3sum/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [3sum](https://leetcode.cn/problems/3sum/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['[-1,0,1,2,-1,-4]', '[0,1,1]', '[0,0,0]']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans=set()\n",
    "        length =len(nums)\n",
    "        if(length<3):return []\n",
    "        for i in range(length-2):\n",
    "            target=-nums[i]\n",
    "            j=i+1\n",
    "            k=length-1\n",
    "            while(j<k):\n",
    "                total=nums[j]+nums[k]\n",
    "                if(total<target):\n",
    "                    j+=1\n",
    "                elif(total>target):\n",
    "                    k-=1\n",
    "                else:\n",
    "                    ans.add((nums[i],nums[j],nums[k]))\n",
    "                    j+=1\n",
    "                    # break\n",
    "        # [0,0,0,0] 重复错误,下进行重复检查 set去重\n",
    "        # print(ans)\n",
    "        answer=list(ans)\n",
    "        # print(answer)\n",
    "        return answer\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        m = len(nums)\n",
    "        for first in range(m - 2):\n",
    "            if first > 0 and nums[first] == nums[first - 1]: continue\n",
    "            target = -nums[first]\n",
    "            second = first + 1\n",
    "            third = m - 1\n",
    "            while second < third:\n",
    "                if second > first + 1 and nums[second] == nums[second - 1]: \n",
    "                    second += 1\n",
    "                    continue\n",
    "                if third < m - 1 and nums[third] == nums[third + 1]: \n",
    "                    third -= 1\n",
    "                    continue\n",
    "                if nums[second] + nums[third] == target:\n",
    "                    ans.append([nums[first], nums[second], nums[third]])\n",
    "                    second += 1\n",
    "                elif nums[second] + nums[third] > target:\n",
    "                    third -= 1\n",
    "                else:\n",
    "                    second += 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        #1e3 1e6<1e8\n",
    "        #这里我的算法还是走进去了，其实可以判定直接跳过\n",
    "\n",
    "\n",
    "        result=[]\n",
    "        r=set()\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            start=i+1\n",
    "            end=len(nums)-1\n",
    "            if i>0 and nums[i]==nums[i-1]:\n",
    "                continue\n",
    "            for j in range(start,end):\n",
    "                if j>start and nums[j]==nums[j-1]:\n",
    "                    continue\n",
    "                while j<end and nums[i]+nums[j]+nums[end]>0:\n",
    "                    end-=1\n",
    "                if j==end:\n",
    "                    break\n",
    "                if nums[i]+nums[j]+nums[end]==0:\n",
    "                    result.append((nums[i],nums[j],nums[end]))\n",
    "        return result\n",
    "             \n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        group = set()\n",
    "        for i in range(len(nums)-2):\n",
    "            j,k = i+1, len(nums) -1\n",
    "            while j < k:\n",
    "                if nums[i] + nums[j] + nums[k] == 0:\n",
    "                    group.add((nums[i], nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                elif  nums[i] + nums[j] + nums[k] > 0:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    j += 1 \n",
    "        return list(group)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        if not nums or len(nums) < 3:\n",
    "            return []\n",
    "        ans = set([])\n",
    "        for i in range(len(nums)):\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1 \n",
    "            while l < r:\n",
    "                if nums[l] + nums[r] + nums[i] < 0:\n",
    "                    l+=1\n",
    "                elif nums[l] + nums[r] + nums[i] > 0:\n",
    "                    r-=1\n",
    "                else: \n",
    "                    ans.add((nums[l] , nums[r] , nums[i]))\n",
    "                    l+=1\n",
    "        return list(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums)<3:\n",
    "            return []\n",
    "        nums.sort()#\n",
    "        target=0\n",
    "        ans =set()\n",
    "        for i in range(len(nums)-2):\n",
    "                now = nums[i]\n",
    "                p=i+1\n",
    "                q=len(nums)-1\n",
    "                while p<q:\n",
    "                    if now+nums[p]+nums[q]==target:\n",
    "                        if (nums[i],nums[p],nums[q]) not in ans:\n",
    "                            ans.add((nums[i],nums[p],nums[q]))\n",
    "                    if now+nums[p]+nums[q] > target:\n",
    "                        q-=1\n",
    "                    else:\n",
    "                        p+=1\n",
    "        return list(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = set()\n",
    "        for i in range(len(nums)):\n",
    "            l = i-1\n",
    "            r = i+1\n",
    "            while l >= 0 and r < len(nums):\n",
    "                s = nums[l] + nums[i] + nums[r]\n",
    "                tmpl = nums[l]\n",
    "                tmpr = nums[r]\n",
    "                if s == 0:\n",
    "\n",
    "                    res.add((nums[l], nums[i], nums[r]))\n",
    "                    r += 1\n",
    "                    l -= 1\n",
    "                elif s < 0:\n",
    "                    r += 1\n",
    "                else:\n",
    "                    l -= 1\n",
    "        return list(res)\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        if not nums or len(nums) < 3:\n",
    "            return []\n",
    "        ans = set([])\n",
    "        for i in range(len(nums)):\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1 \n",
    "            while l < r:\n",
    "                if nums[l] + nums[r] + nums[i] < 0:\n",
    "                    l+=1\n",
    "                elif nums[l] + nums[r] + nums[i] > 0:\n",
    "                    r-=1\n",
    "                else: \n",
    "                    ans.add((nums[l] , nums[r] , nums[i]))\n",
    "                    l+=1\n",
    "        return list(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums = sorted(nums)\n",
    "        ans = set()\n",
    "        for i in range(len(nums)-2):\n",
    "            l, r = i+1, len(nums)-1\n",
    "            while l < r:\n",
    "                if nums[i]+nums[l]+nums[r] == 0:\n",
    "                    ans.add((nums[i], nums[l], nums[r]))\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                elif nums[i]+nums[l]+nums[r] < 0:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return list(ans)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "\n",
    "        for a in range(len(nums)-2):\n",
    "            if a > 0 and nums[a] == nums[a-1]:\n",
    "                continue\n",
    "\n",
    "            c = len(nums) - 1\n",
    "            for b in range(a+1, len(nums)-1):\n",
    "                if b > a+1 and nums[b] == nums[b-1]:\n",
    "                    continue\n",
    "                if nums[a] + nums[b] + nums[c] < 0:\n",
    "                    continue\n",
    "                while b < c and nums[a] + nums[b] + nums[c] > 0:\n",
    "                    c -= 1\n",
    "                if b == c:\n",
    "                    break\n",
    "                if b < c and nums[a] + nums[b] + nums[c] == 0:\n",
    "                    res.append((nums[a], nums[b], nums[c]))\n",
    "\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "\n",
    "        for a in range(len(nums)-2):\n",
    "            if a > 0 and nums[a] == nums[a-1]:\n",
    "                continue\n",
    "\n",
    "            c = len(nums) - 1\n",
    "            for b in range(a+1, len(nums)-1):\n",
    "                if b > a+1 and nums[b] == nums[b-1]:\n",
    "                    continue\n",
    "\n",
    "                while b < c and nums[a] + nums[b] + nums[c] > 0:\n",
    "                    c -= 1\n",
    "                if b == c:\n",
    "                    break\n",
    "                if nums[a] + nums[b] + nums[c] == 0:\n",
    "                    res.append((nums[a], nums[b], nums[c]))\n",
    "\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        res = set()\n",
    "        n = len(nums)\n",
    "        if n < 3:\n",
    "            return []\n",
    "        \n",
    "        nums.sort()\n",
    "        for i in range(n-2):\n",
    "            left, right = i + 1, n - 1\n",
    "            while left < right:\n",
    "                if nums[i] + nums[left] + nums[right] == 0:\n",
    "                    res.add((nums[i], nums[left], nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif nums[i] + nums[left] + nums[right] < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return list(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "\n",
    "        for a in range(len(nums)-2):\n",
    "            if a > 0 and nums[a] == nums[a-1]:\n",
    "                continue\n",
    "\n",
    "            c = len(nums) - 1\n",
    "            for b in range(a+1, len(nums)-1):\n",
    "                if b >= c:\n",
    "                    break\n",
    "                if b > a+1 and nums[b] == nums[b-1]:\n",
    "                    continue\n",
    "                if nums[a] + nums[b] + nums[c] < 0:\n",
    "                    continue\n",
    "                while b < c and nums[a] + nums[b] + nums[c] > 0:\n",
    "                    c -= 1\n",
    "                if b < c and nums[a] + nums[b] + nums[c] == 0:\n",
    "                    res.append((nums[a], nums[b], nums[c]))\n",
    "\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "\n",
    "        for a in range(len(nums)-2):\n",
    "            if a > 0 and nums[a] == nums[a-1]:\n",
    "                continue\n",
    "\n",
    "            c = len(nums) - 1\n",
    "            for b in range(a+1, len(nums)-1):\n",
    "                if b > a+1 and nums[b] == nums[b-1]:\n",
    "                    continue\n",
    "\n",
    "                while b < c and nums[a] + nums[b] + nums[c] > 0:\n",
    "                    c -= 1\n",
    "                if b == c:\n",
    "                    break\n",
    "                if nums[a] + nums[b] + nums[c] == 0:\n",
    "                    res.append((nums[a], nums[b], nums[c]))\n",
    "\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        s = []\n",
    "        if nums.count(0) >= 3:\n",
    "            s.append([0, 0, 0])\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            if nums[i] >= 0:\n",
    "                break\n",
    "            l1 = nums[i + 1:]\n",
    "            a = 0\n",
    "            b = n - i - 1 - 1\n",
    "            while a < b:\n",
    "                c = l1[a] + l1[b]\n",
    "                if -c > nums[i]:\n",
    "                    a += 1\n",
    "                elif -c < nums[i]:\n",
    "                    b -= 1\n",
    "                else:\n",
    "                    l2 = [-c, l1[a], l1[b]]\n",
    "                    l2.sort()\n",
    "                    if l2 not in s:\n",
    "                        s.append(l2)\n",
    "                    a += 1\n",
    "        return s\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        ans = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            j = i + 1\n",
    "            k = len(nums) - 1\n",
    "            while j <k :\n",
    "                if nums[i] + nums[j] + nums[k] == 0:\n",
    "                    ans.append((nums[i], nums[j], nums[k]))\n",
    "                    while j < k and nums[j] == nums[j+1]:\n",
    "                        j += 1\n",
    "                    while j < k and nums[k] == nums[k-1]:\n",
    "                        k -= 1\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                elif nums[i] + nums[j] + nums[k] < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    k -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        arr_target = [-i for i in nums[:-2]]\n",
    "        ret = []\n",
    "        tmp = []\n",
    "        for index, target in enumerate(arr_target):\n",
    "            left = index + 1\n",
    "            right = len(nums) - 1\n",
    "            while left < right:\n",
    "                l = nums[left]\n",
    "                r = nums[right]\n",
    "               #剪枝\n",
    "                if l > target:\n",
    "                    break\n",
    "                elif l + r == target:\n",
    "                    tmp = sorted([-target, l, r])\n",
    "                    if tmp not in ret:\n",
    "                        ret.append(tmp)\n",
    "                    left += 1\n",
    "                elif l + r > target:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left +=1\n",
    "        return ret\n",
    "\n",
    "\n",
    "\n",
    "                \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        arr_target = [-i for i in nums[:-2]]\n",
    "        ret = []\n",
    "        tmp = []\n",
    "        for index, target in enumerate(arr_target):\n",
    "            left = index + 1\n",
    "            right = len(nums) - 1\n",
    "            while left < right:\n",
    "                l = nums[left]\n",
    "                r = nums[right]\n",
    "                # if l > target:\n",
    "                #     break\n",
    "                # elif l + r == target:\n",
    "                if l + r == target:\n",
    "                    tmp = sorted([-target, l, r])\n",
    "                    if tmp not in ret:\n",
    "                        ret.append(tmp)\n",
    "                    left += 1\n",
    "                elif l + r > target:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left +=1\n",
    "        return ret\n",
    "\n",
    "\n",
    "\n",
    "                \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        res = []\n",
    "        nums = list(sorted(nums))\n",
    "        for i,a in enumerate(nums):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            target = 0 - a\n",
    "            left,right = i+1, len(nums)-1\n",
    "            while left < right:\n",
    "                if nums[left] + nums[right] == target:\n",
    "                    res.append((a,nums[left],nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                    while nums[right] == nums[right+1] and left < right:\n",
    "                        right -= 1\n",
    "                    while nums[left] == nums[left-1] and left < right:\n",
    "                        left += 1\n",
    "                elif nums[left] + nums[right] > target:\n",
    "                    right -=1\n",
    "                elif nums[left] + nums[right] < target:\n",
    "                    left += 1\n",
    "        return res\n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        ans = []\n",
    "        n = len(nums)\n",
    "        nums = sorted(nums)\n",
    "        for i in range(n-2):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            l = i+1\n",
    "            r = n-1\n",
    "            while l < r:\n",
    "                if (s:= nums[i]+nums[l]+nums[r]) == 0:\n",
    "                    ans.append([nums[i], nums[l], nums[r]])\n",
    "                    while l < r and nums[l] == nums[l+1]: l += 1\n",
    "                    while l <  r and nums[r] == nums[r-1]: r -= 1\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                elif s > 0:\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    l += 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        # 数组：双指针\n",
    "        ret = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            left, right = i + 1, len(nums) - 1\n",
    "            while left < right:\n",
    "                sums = nums[i] + nums[left] + nums[right]\n",
    "                if sums > 0:\n",
    "                    right -= 1\n",
    "                elif sums < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    ret.append([nums[i], nums[left], nums[right]])\n",
    "                    while left < right and nums[left] == nums[left + 1]:\n",
    "                        left += 1\n",
    "                    while left < right and nums[right] == nums[right - 1]:\n",
    "                        right -= 1\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        res = []\n",
    "        dic = defaultdict(int)       \n",
    "        for i in nums:\n",
    "            dic[i] += 1\n",
    "        nums = sorted(dic)             \n",
    "        for i, x in enumerate(nums):   \n",
    "            if x == 0 and dic[x] > 2:      \n",
    "                res.append([0, 0, 0])      \n",
    "            elif x != 0 and dic[x] > 1:    \n",
    "                if -(x<<1) in dic:          \n",
    "                    res.append([x, x, -(x<<1)])\n",
    "            if x < 0:                     \n",
    "                y_z = -x                                       \n",
    "                z_id = bisect.bisect_right(nums, y_z>>1, i+1) # 求得 y_z//2 的下标\n",
    "                for z in nums[z_id:]:                          \n",
    "                    y = y_z - z\n",
    "                    if y > x and y in dic:\n",
    "                        res.append([x, y, z])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) >= 3 and len(set(nums)) == 1 and nums[0] == 0: return [nums[:3]]\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        n = len(nums)\n",
    "        for i in range(n-2):\n",
    "            x = nums[i]\n",
    "            if x == nums[i-1]:\n",
    "                continue\n",
    "            if x + nums[i+1] + nums[i+2] > 0:\n",
    "                break\n",
    "            if x + nums[-2] + nums[-1] < 0:\n",
    "                continue\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            while j < k:\n",
    "                s = x + nums[j] + nums[k]\n",
    "                if s > 0:\n",
    "                    k -= 1\n",
    "                elif s < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    ans.append([x, nums[j], nums[k]])\n",
    "                    j += 1\n",
    "                    while j < k and nums[j] == [j-1]:\n",
    "                        j += 1\n",
    "                    k -= 1\n",
    "                    while k > j and nums[k] == nums[k+1]:\n",
    "                        k -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        if n < 3:\n",
    "            return []\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        for i in range(0, n - 2):\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            while j < k:\n",
    "                if nums[i] + nums[j] + nums[k] == 0:\n",
    "                    res.append([nums[i], nums[j], nums[k]])\n",
    "                    while j < k and nums[k] == nums[k - 1]:\n",
    "                        k -= 1\n",
    "                    while j < k and nums[j] == nums[j + 1]:\n",
    "                        j += 1\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                elif nums[i] + nums[k] + nums[j] < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    k -= 1\n",
    "        return res\n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 方法一\n",
    "# 标签：数组遍历\n",
    "# 首先对数组进行排序，排序后固定一个数 nums[i]nums[i]nums[i]，再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端，数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R]，计算三个数的和 sumsumsum 判断是否满足为 000，满足则添加进结果集\n",
    "# 如果 nums[i]nums[i]nums[i]大于 000，则三数之和必然无法等于 000，结束循环\n",
    "# 如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1]，则说明该数字重复，会导致结果重复，所以应该跳过\n",
    "# 当 sumsumsum == 000 时，nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复，应该跳过，L++\n",
    "# 当 sumsumsum == 000 时，nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复，应该跳过，R−−\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if not nums or len(nums) < 3:\n",
    "            return []\n",
    "        \n",
    "        ans = []\n",
    "        nums.sort()\n",
    "        for i in range(0, len(nums)):\n",
    "            if nums[i] > 0: # 因为排序过，所以第一个数》0了，sum三数之和肯定大于0了\n",
    "                break\n",
    "            if i > 0 and nums[i] == nums[i-1]: # 去重第一个数\n",
    "                continue\n",
    "            \n",
    "            # 左右指针从两边向中间对齐\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1\n",
    "            while l < r:\n",
    "                sum = nums[i] + nums[l] + nums[r]\n",
    "                left = nums[l]\n",
    "                right = nums[r]\n",
    "                if sum == 0:\n",
    "                    ans.append([nums[i], nums[l], nums[r]])\n",
    "                    # 去重第二、第三个数\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                    # l += 1\n",
    "                    # r -= 1\n",
    "                elif sum < 0:\n",
    "                    l += 1\n",
    "                elif sum > 0:\n",
    "                    r -= 1\n",
    "        return ans\n",
    "\n",
    "\n",
    "# 方法二：labuladong 排序+双指针,可以通过。但是这个方法用在4Sum，无法通过\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         nums.sort()\n",
    "#         # n 为 3，从 nums[0] 开始计算和为 0 的三元组\n",
    "#         # n 填写想求的是几数之和，start 从哪个索引开始计算（一般填 0），target 填想凑出的目标和\n",
    "#         ans = self.nSumTarget(nums, 3, 0, 0)\n",
    "\n",
    "#         return ans\n",
    "    \n",
    "#     def nSumTarget(self, nums, n, start, target):\n",
    "#         if len(nums) < n:\n",
    "#             return []\n",
    "#         if n < 2:# 至少是2Sum\n",
    "#             return []\n",
    "        \n",
    "#         ans = []\n",
    "        \n",
    "#         if n == 2: # 就是最好写的两数之和\n",
    "#         # 双指针那一套操作\n",
    "#             l, r = start, len(nums) - 1\n",
    "#             while l < r:\n",
    "#                 sum_ = nums[l] + nums[r]\n",
    "#                 left, right = nums[l], nums[r]\n",
    "#                 if sum_ == target:\n",
    "#                     ans.append([left, right])\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                 elif sum_ > target:\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                 elif sum_ < target:\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#         else:\n",
    "#             # 大于2Sum的，先求n-1\n",
    "#             # n > 2 时，递归计算 (n-1)Sum 的结果，就想象成3Sum的，比较好理解\n",
    "#             for i in range(start, len(nums)):\n",
    "#                 if i > 0 and nums[i] == nums[i-1]: #去重\n",
    "#                     continue\n",
    "\n",
    "#                 target_ = target - nums[i]\n",
    "#                 sub = self.nSumTarget(nums, n - 1, i + 1, target_)\n",
    "#                 for arr in sub:\n",
    "#                     # (n-1)Sum 加上 nums[i] 就是 nSum\n",
    "#                     arr.append(nums[i])\n",
    "#                     ans.append(arr) # 这里的ans是指最外层的ans，是[]。递归时候最里层的ans被用掉了，不为空。但代码跑到这时，用的是最外层的ans，为[]\n",
    "        \n",
    "#         return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ans = []\n",
    "        for first in range(n):\n",
    "            if first > 0 and nums[first] == nums[first-1]:\n",
    "                continue\n",
    "            third = n - 1\n",
    "            target = -nums[first]\n",
    "\n",
    "            for second in range(first+1, n):\n",
    "                if second > first + 1 and nums[second] == nums[second-1]:\n",
    "                    continue\n",
    "                while second < third and nums[second] + nums[third] > target:\n",
    "                    third -= 1\n",
    "                if second == third:\n",
    "                    break\n",
    "                if nums[second] + nums[third] == target:\n",
    "                    ans.append([nums[first], nums[second], nums[third]])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n, ans = len(nums), []\n",
    "        pre_i = pre_j = 114514\n",
    "        nums.sort()\n",
    "        for i in range(n-2):\n",
    "            ni = nums[i]\n",
    "            if ni == pre_i:\n",
    "                continue\n",
    "            pre_i = ni\n",
    "\n",
    "            for j in range(i+1, n-1):\n",
    "                nj = nums[j]\n",
    "                if nj == pre_j:\n",
    "                    continue\n",
    "                pre_j = nj\n",
    "                k = bisect.bisect_left(nums, -ni-nj, lo=j+1)\n",
    "                if k < n and ni+nj+nums[k] == 0:\n",
    "                    ans.append([ni, nj, nums[k]])\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        l = len(nums)\n",
    "        if l<3:\n",
    "            return []\n",
    "        rs = []\n",
    "        for i in range(l-2):\n",
    "            a = nums[i]\n",
    "            if a>0:\n",
    "                break\n",
    "            if i>0 and a==nums[i-1]:  # 去重\n",
    "                continue\n",
    "            st, ed = i+1, l-1\n",
    "\n",
    "            while st<ed:\n",
    "                b, c = nums[st], nums[ed]\n",
    "                if a+b+c==0:\n",
    "                    rs.append([a, b, c])\n",
    "                    st += 1\n",
    "                    ed -= 1\n",
    "                    while st<ed and nums[st]==nums[st-1]:\n",
    "                        st += 1\n",
    "                    while st<ed and nums[ed]==nums[ed+1]:\n",
    "                        ed -= 1\n",
    "                elif a+b+c<0:\n",
    "                    st += 1\n",
    "                else:\n",
    "                     ed -= 1\n",
    "        return rs\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "\n",
    "        for i in range(len(nums)):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            a = nums[i]\n",
    "            l, r = i+1, len(nums)-1\n",
    "            \n",
    "            while l < r:\n",
    "                if l < r and l > i+1 and nums[l] == nums[l-1]:\n",
    "                    l += 1\n",
    "                    continue\n",
    "                if l < r and r < len(nums)-1 and nums[r] == nums[r+1]:\n",
    "                    r -= 1\n",
    "                    continue\n",
    "                b, c = nums[l], nums[r]\n",
    "                if a+b+c == 0:\n",
    "                    res.append([a, b, c])\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                elif a+b+c < 0:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            l,r = i+1,n-1\n",
    "            while l<r:\n",
    "                if nums[l]+nums[r]==-nums[i]:\n",
    "                    t = [nums[i],nums[l],nums[r]]\n",
    "                    if t not in(res):\n",
    "                        res.append(t)\n",
    "                    l+=1\n",
    "                    r-=1\n",
    "                elif nums[l]+nums[r]<-nums[i]:\n",
    "                    l+=1\n",
    "                else:\n",
    "                    r-=1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        for i in range(n-2):\n",
    "            a = nums[i]\n",
    "            if i > 0 and a == nums[i-1]:\n",
    "                continue\n",
    "            if a + nums[i+1] + nums[i+2] > 0:\n",
    "                break\n",
    "            if a + nums[-1] + nums[-2] < 0:\n",
    "                continue\n",
    "            j, k = i+1, n-1\n",
    "            while j < k:\n",
    "                b, c = nums[j], nums[k]\n",
    "                if j > i+1 and b == nums[j-1]:\n",
    "                    j += 1\n",
    "                    continue\n",
    "                if k < n-1 and c == nums[k+1]:\n",
    "                    k -= 1\n",
    "                    continue\n",
    "                s = a + b + c\n",
    "                if s < 0:\n",
    "                    j += 1\n",
    "                elif s > 0:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    ans.append([a, b, c])\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            if i>0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            l, r = i+1, n-1\n",
    "            while l<r:\n",
    "                if l<r and nums[i] + nums[l]+nums[r] == 0:\n",
    "                    res.append([nums[i], nums[l], nums[r]])\n",
    "                    l+=1\n",
    "                    r-=1\n",
    "                    while l<r and nums[l] == nums[l-1]:\n",
    "                        l+=1\n",
    "                    while l<r and nums[r]>nums[r+1]:\n",
    "                        r-=1\n",
    "                elif l<r and nums[i] + nums[l]+nums[r] < 0:\n",
    "                    l += 1\n",
    "                elif l<r and nums[i] + nums[l]+nums[r] > 0:\n",
    "                    r -= 1\n",
    "        return res\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n=len(nums)\n",
    "        ans=[]\n",
    "        for i in range(n-2):\n",
    "            if i>0 and nums[i]==nums[i-1]:\n",
    "                continue\n",
    "            j,k=i+1,n-1\n",
    "            while j<k:\n",
    "                if j>i+1 and nums[j]==nums[j-1]:\n",
    "                    j+=1\n",
    "                    continue\n",
    "                if nums[j]+nums[k]==-nums[i]:\n",
    "                    if (tmp:=[nums[i],nums[j],nums[k]]) not in ans:\n",
    "                        ans.append(tmp)\n",
    "                    j+=1\n",
    "                    k-=1\n",
    "                elif nums[j]+nums[k]>-nums[i]:\n",
    "                    k-=1\n",
    "                else:\n",
    "                    j+=1\n",
    "        return ans\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n=len(nums)\n",
    "        ans=[]\n",
    "        for i in range(n-2):\n",
    "            j,k=i+1,n-1\n",
    "            while j<k:\n",
    "                if nums[j]+nums[k]==-nums[i]:\n",
    "                    if (tmp:=[nums[i],nums[j],nums[k]]) not in ans:\n",
    "                        ans.append(tmp)\n",
    "                    j+=1\n",
    "                    k-=1\n",
    "                elif nums[j]+nums[k]>-nums[i]:\n",
    "                    k-=1\n",
    "                else:\n",
    "                    j+=1\n",
    "        return ans\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        for i in range(n):\n",
    "            if nums[i] > 0:\n",
    "                return ans  #返回ans而不是[]\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            left, right = i + 1, n - 1\n",
    "            while left < right:\n",
    "                sums = nums[i] + nums[left] + nums[right]\n",
    "                if sums > 0:\n",
    "                    right -= 1\n",
    "                elif sums < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    ans.append([nums[i], nums[left], nums[right]])\n",
    "                    while left < right and nums[left + 1] == nums[left]:\n",
    "                        left += 1\n",
    "                    while left < right and nums[right - 1] == nums[right]:\n",
    "                        right -= 1\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        res = []\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        for cur in range(len(nums)):\n",
    "            # 对cur进行去重\n",
    "            if nums[cur] > 0:\n",
    "                return res\n",
    "            if cur >= 1 and nums[cur] == nums[cur - 1]:\n",
    "                continue\n",
    "            left = cur + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                total = nums[cur] + nums[left] + nums[right]\n",
    "                if total > 0 :\n",
    "                    right -= 1\n",
    "                elif total < 0 :\n",
    "                    left += 1\n",
    "                else:\n",
    "                    res.append([nums[cur],nums[left],nums[right]]) #收集符合条件的数据\n",
    "                    # 对left 和right 进行去重\n",
    "                    while left < right and nums[left + 1] == nums[left]:\n",
    "\n",
    "                        left += 1\n",
    "                    while left < right and nums[right-1] == nums[right]:\n",
    "\n",
    "                        right -= 1\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ans =[]\n",
    "        for i in range(0,n-2):\n",
    "            target = -nums[i]\n",
    "\n",
    "            if i>0 and nums[i]==nums[i-1]:\n",
    "                continue # 目标值相同则不重复搜索\n",
    "            left = i+1\n",
    "            right = n-1\n",
    "\n",
    "            while left<right:\n",
    "                s=nums[left]+nums[right]\n",
    "                if s==target:\n",
    "                    ans.append([nums[i], nums[left], nums[right]])\n",
    "                \n",
    "                    while left<right and nums[left]==nums[left+1]:\n",
    "                        left+=1\n",
    "                    while left<right and nums[right]==nums[right-1]:\n",
    "                        right-=1\n",
    "                    left+=1  # 跳出重复范围继续搜索\n",
    "                    right-=1\n",
    "\n",
    "                # 为了最外层while循环能正常终止，以下这两行不要忘记\n",
    "                if s>target:\n",
    "                    right-=1\n",
    "                if s<target:\n",
    "                    left+=1\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        #print(nums)\n",
    "        def find(l,r,target):\n",
    "            if l>r:\n",
    "                return r\n",
    "            now = (l+r) // 2\n",
    "            if nums[now] == target:\n",
    "                return now\n",
    "            if nums[now] < target:\n",
    "                return find(now+1,r,target)\n",
    "            if nums[now] > target:\n",
    "                return find(l,now-1,target)\n",
    "        res = []\n",
    "        i = 0\n",
    "        while(i<n-2):\n",
    "            r = n-1\n",
    "            j = i+1\n",
    "            while(j<n-1):\n",
    "                target = 0-(nums[i]+nums[j])\n",
    "                #print(target, nums[i], nums[j])\n",
    "                l = j+1\n",
    "                if nums[r] >= target and nums[l] <= target and l<=r:\n",
    "                    r = find(l,r,target)\n",
    "                    #print(r,nums[r])\n",
    "                    if nums[r] == target:\n",
    "                        res.append([nums[i],nums[j],nums[r]])\n",
    "                        r -= 1\n",
    "                j += 1\n",
    "                while(j<n and nums[j-1]==nums[j]):\n",
    "                    j += 1\n",
    "            i += 1\n",
    "            while(i<n and nums[i-1]==nums[i]):\n",
    "                i += 1\n",
    "        return res    \n",
    "        '''\n",
    "        n = len(nums)\n",
    "        s = {}\n",
    "        for num in nums:\n",
    "            if num in s.keys():\n",
    "                s[num] += 1\n",
    "            else:\n",
    "                s[num] = 1\n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            if s[nums[i]] == 0:\n",
    "                continue\n",
    "            s[nums[i]] -= 1\n",
    "            s_tmp = s.copy()\n",
    "            for j in range(i+1,n):\n",
    "                if s_tmp[nums[j]] == 0:\n",
    "                    continue\n",
    "                s_tmp[nums[j]] -= 1\n",
    "                target = (0-nums[i]-nums[j])\n",
    "                if s_tmp.get(target, 0) > 0:\n",
    "                    res.append([nums[i], nums[j], target])\n",
    "                s_tmp[nums[j]] = 0\n",
    "            s[nums[i]] = 0\n",
    "        return res\n",
    "        '''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = list()\n",
    "        n = len(nums)\n",
    "\n",
    "        for first in range(n):\n",
    "            if first > 0 and nums[first] == nums[first - 1]:\n",
    "                continue\n",
    "\n",
    "            third = n - 1\n",
    "            target = -nums[first]\n",
    "            for second in range(first + 1, n):\n",
    "                if second > first + 1 and nums[second] == nums[second - 1]:\n",
    "                    continue\n",
    "\n",
    "                while second < third and nums[second] + nums[third] > target:\n",
    "                    third -= 1\n",
    "\n",
    "                if second == third:\n",
    "                    break\n",
    "                if nums[second] + nums[third] == target:\n",
    "                    ans.append([nums[first], nums[second], nums[third]])\n",
    "        \n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        for first in range(n):\n",
    "            if first > 0 and nums[first] == nums[first - 1]:\n",
    "                continue\n",
    "            target = -nums[first]\n",
    "            third = n - 1\n",
    "            for second in range(first + 1, n):\n",
    "                if second > first + 1 and nums[second] == nums[second - 1]:\n",
    "                    continue\n",
    "                while third > second and nums[second] + nums[third] > target:\n",
    "                    third -= 1\n",
    "                if second == third:\n",
    "                    break\n",
    "                if nums[third] + nums[second] == target:\n",
    "                    ans.append([nums[first], nums[second], nums[third]])\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        hash_map = {}\n",
    "        for i in range(n):\n",
    "            hash_map[nums[i]] = i\n",
    "        results = []\n",
    "        # sets = set()\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n):\n",
    "                if - nums[i] - nums[j] in hash_map and hash_map[- nums[i] - nums[j]] != i and hash_map[- nums[i] - nums[j]] != j:\n",
    "                    # ele = set([nums[i], nums[j], hash_map[- nums[i] - nums[j]]])\n",
    "                    ele = sorted([nums[i], nums[j], nums[hash_map[- nums[i] - nums[j]]]])\n",
    "                    if ele not in results:\n",
    "                        results.append(ele)\n",
    "        return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        def find(l,r,target):\n",
    "            if l>r:\n",
    "                return r\n",
    "            now = (l+r) // 2\n",
    "            if nums[now] == target:\n",
    "                return now\n",
    "            if nums[now] < target:\n",
    "                return find(now+1,r,target)\n",
    "            if nums[now] > target:\n",
    "                return find(l,now-1,target)\n",
    "        res = []\n",
    "        i = 0\n",
    "        while(i<n-2):\n",
    "            if nums[i] + nums[i+1] + nums[i+2] > 0:\n",
    "                break\n",
    "            r = n-1\n",
    "            j = i+1\n",
    "            while(j<n-1):\n",
    "                target = 0-(nums[i]+nums[j])\n",
    "                l = j+1\n",
    "                if nums[l] > target:\n",
    "                    break\n",
    "                if nums[r] >= target and nums[l] <= target and l<=r:\n",
    "                    r = find(l,r,target)\n",
    "                    if nums[r] == target:\n",
    "                        res.append([nums[i],nums[j],nums[r]])\n",
    "                        r -= 1\n",
    "                j += 1\n",
    "                while(j<n and nums[j-1]==nums[j]):\n",
    "                    j += 1\n",
    "            i += 1\n",
    "            while(i<n and nums[i-1]==nums[i]):\n",
    "                i += 1\n",
    "        return res    \n",
    "        '''\n",
    "        n = len(nums)\n",
    "        s = {}\n",
    "        for num in nums:\n",
    "            if num in s.keys():\n",
    "                s[num] += 1\n",
    "            else:\n",
    "                s[num] = 1\n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            if s[nums[i]] == 0:\n",
    "                continue\n",
    "            s[nums[i]] -= 1\n",
    "            s_tmp = s.copy()\n",
    "            for j in range(i+1,n):\n",
    "                if s_tmp[nums[j]] == 0:\n",
    "                    continue\n",
    "                s_tmp[nums[j]] -= 1\n",
    "                target = (0-nums[i]-nums[j])\n",
    "                if s_tmp.get(target, 0) > 0:\n",
    "                    res.append([nums[i], nums[j], target])\n",
    "                s_tmp[nums[j]] = 0\n",
    "            s[nums[i]] = 0\n",
    "        return res\n",
    "        '''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]: \n",
    "        d=Counter(nums)\n",
    "        ans=list(d.keys())\n",
    "        ans.sort()\n",
    "        n=len(ans)\n",
    "\n",
    "        ret=[]\n",
    "        print(ans)\n",
    "        for i in range(n):\n",
    "            x=n-1\n",
    "            if ans[i]>=0:\n",
    "                break\n",
    "            if d[ans[i]]>1 and d.get(-(2*ans[i]),0):\n",
    "                ret.append([ans[i],ans[i],-(2*ans[i])])\n",
    "            for j in range(i+1,n):\n",
    "                if ans[i]+ans[j]>0:\n",
    "                    break\n",
    "                if d[ans[j]]>1 and 2*ans[j]+ans[i]==0:\n",
    "                    ret.append([ans[i],ans[j],ans[j]])\n",
    "                while x>j and ans[j]+ans[i]>-ans[x]:\n",
    "                    x-=1\n",
    "                if x==j:\n",
    "                    break\n",
    "                if ans[i]+ans[j]+ans[x]==0:\n",
    "                    ret.append([ans[i],ans[j],ans[x]])\n",
    "        if d.get(0,0)>2:\n",
    "            ret.append([0,0,0])\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "\n",
    "        def process(nums,tar):\n",
    "            i,j = 0,len(nums) - 1\n",
    "            result = []\n",
    "            hashmap = set()\n",
    "            while i < j:\n",
    "                if nums[i] in hashmap:\n",
    "                    i += 1\n",
    "                    continue\n",
    "                if nums[j] in hashmap:\n",
    "                    j -= 1\n",
    "                    continue\n",
    "\n",
    "                cur = nums[i] + nums[j]\n",
    "                if cur > tar:\n",
    "                    j -= 1\n",
    "                elif cur < tar:\n",
    "                    i += 1\n",
    "                else:\n",
    "                    if nums[i] not in hashmap or nums[j] not in hashmap:\n",
    "                        result.append([nums[i],nums[j],-1*tar])\n",
    "                        hashmap.add(nums[i])\n",
    "                        hashmap.add(nums[j])\n",
    "                    i += 1\n",
    "                    j -= 1\n",
    "            return result\n",
    "        \n",
    "        nums.sort()\n",
    "        result = []\n",
    "        last = None\n",
    "        while len(nums) > 2:\n",
    "\n",
    "            tar = nums.pop() \n",
    "            if last == tar:\n",
    "                continue\n",
    "            last = tar\n",
    "            tp = process(nums,-1*tar)\n",
    "            if tp:\n",
    "                result.extend(tp)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        l = len(nums)\n",
    "        if l <= 2:\n",
    "            return []\n",
    "        res = []\n",
    "        nums.sort()\n",
    "        next = [l] * l\n",
    "        last = [-1] * l\n",
    "        for i in range(l - 2, -1, -1):\n",
    "            if nums[i] == nums[i + 1]:\n",
    "                next[i] = next[i + 1]\n",
    "            else:\n",
    "                next[i] = i + 1\n",
    "        for i in range(1, l):\n",
    "            if nums[i] == nums[i - 1]:\n",
    "                last[i] = last[i - 1]\n",
    "            else:\n",
    "                last[i] = i - 1\n",
    "        i, j, k = 0, 1, l - 1\n",
    "        while True:\n",
    "            if nums[i] + nums[j] + nums[k] < 0:\n",
    "                j = next[j]\n",
    "                if j == k:\n",
    "                    j += 1\n",
    "            elif nums[i] + nums[j] + nums[k] > 0:\n",
    "                k = last[k]\n",
    "                if k == j:\n",
    "                    k -= 1\n",
    "            elif nums[i] + nums[j] + nums[k] == 0:\n",
    "                res.append([nums[i], nums[j], nums[k]])\n",
    "                j = next[j]\n",
    "            if j > k:\n",
    "                i = next[i]\n",
    "                j = i + 1\n",
    "                k = l - 1\n",
    "                if i >= l - 2:\n",
    "                    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        if n < 3:return []\n",
    "        dic = Counter(nums)\n",
    "        ans = set()\n",
    "        nums.sort()\n",
    "        for i in range(n-2):\n",
    "            for j in range(i+1,n-1):\n",
    "                t = 0 - nums[i] - nums[j]\n",
    "                if t<nums[j]:\n",
    "                    break\n",
    "                elif t in dic:\n",
    "                    if t == 0:\n",
    "                        if dic[0]>2:\n",
    "                            ans.add((0,0,0))\n",
    "                    elif t == nums[j]:\n",
    "                        if dic[t]>1:\n",
    "                            ans.add((nums[i],nums[j],t))\n",
    "                    else:\n",
    "                        ans.add((nums[i],nums[j],t))\n",
    "        return [list(i) for i in ans]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        sorted_nums = sorted(nums)\n",
    "        n = len(nums) \n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            target = - sorted_nums[i]\n",
    "            start = i + 1\n",
    "            end = n - 1\n",
    "            while start < end:\n",
    "                temp = sorted_nums[start] + sorted_nums[end]\n",
    "                if  temp == target:\n",
    "                    temp_res = [-target, sorted_nums[start], sorted_nums[end]]\n",
    "                    if temp_res not in res:\n",
    "                        res.append(temp_res)\n",
    "                    end -= 1\n",
    "                elif temp > target:\n",
    "                    end -= 1\n",
    "                else: \n",
    "                    start += 1\n",
    "            \n",
    "            \n",
    "            # print(temp, start, end)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        #回溯时间太长，\n",
    "        # ans = []\n",
    "        # p = []\n",
    "        # nums.sort()\n",
    "        # used = [0]*len(nums)\n",
    "        # #回溯+这里的元素不可重复，因此设置一个索引\n",
    "        # def backtrac(num_arry,index,path,target):\n",
    "        #     if len(path) == 3 and target==0:\n",
    "        #         ans.append(path[:])\n",
    "        #         return\n",
    "            \n",
    "        #     if len(path)>3 or index>=len(num_arry):\n",
    "        #         return\n",
    "        #     if used[index]==1:\n",
    "        #         return \n",
    "        #     #我这里的情况是元素被重复使用了\n",
    "        #     for i in range(index,len(num_arry)):#这里如何约束\n",
    "        #         path.append(num_arry[i])\n",
    "        #         target -= num_arry[i]\n",
    "        #         used[i] = 1\n",
    "        #         backtrac(num_arry,i+1,path,target)\n",
    "        #         used[i] = 0\n",
    "        #         target += num_arry[i]\n",
    "        #         path.pop()\n",
    "\n",
    "        # #注意上面的for里面不返回，只有在符合条件时才返回\n",
    "        # backtrac(nums,0,p,0)\n",
    "        # #去重\n",
    "        # new_ans = []\n",
    "        # for value in ans:\n",
    "        #     if value not in new_ans:\n",
    "        #         new_ans.append(value)\n",
    "        # return new_ans\n",
    "\n",
    "        #所有查收元素和的问题都是双指针+排序\n",
    "        #和大于目标时，right--;和小于目标时，left ++\n",
    "        #三个数字时，迭代计算\n",
    "        #是否可以固定一个，然后left是他后面的位置\n",
    "        nums.sort()\n",
    "        #从0开始计算和为0的三元组\n",
    "        return self.nsumtarget(nums,3,0,0)#长度为3，开始位置为0，和为0\n",
    "\n",
    "    def nsumtarget(self,nums,n,index,target):\n",
    "        #判断一些可以直接排除的情况\n",
    "        sz = len(nums)\n",
    "        res = []\n",
    "        if n<2 or sz<n:\n",
    "            return res\n",
    "        #如果只只需查找两个\n",
    "        if n==2:\n",
    "            left = index\n",
    "            right = sz-1\n",
    "            while left<right:\n",
    "                sum_ = nums[left]+nums[right]\n",
    "                lv  = nums[left]\n",
    "                rv = nums[right]\n",
    "                #判断情况，觉得指针的移动情况\n",
    "                if sum_ == target:\n",
    "                    res.append([nums[left],nums[right]])\n",
    "                    #继续移动\n",
    "                    while left<right and nums[left]==lv:\n",
    "                        left += 1\n",
    "                    while left<right and nums[right] ==  rv:\n",
    "                        right -=1\n",
    "                elif sum_ < target:\n",
    "                    while left<right and nums[left] == lv:#跳过重复的元素\n",
    "                        left+=1\n",
    "                elif sum_>target:\n",
    "                    while left<right and nums[right]==rv:\n",
    "                        right -=1\n",
    "        else:\n",
    "            #元组长度大于2时，需要递归n-1的长度，然后添加上当前的值\n",
    "            for i in range(index,sz):#固定一个查找值\n",
    "                if i>0 and nums[i]==nums[i-1]:\n",
    "                    continue         \n",
    "                sub = self.nsumtarget(nums,n-1,i+1,target-nums[i])\n",
    "                for arr in sub:\n",
    "                    arr.append(nums[i])\n",
    "                    res.append(arr)\n",
    "\n",
    "        return res\n",
    "                \n",
    "\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 方法一\n",
    "# 标签：数组遍历\n",
    "# 首先对数组进行排序，排序后固定一个数 nums[i]nums[i]nums[i]，再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端，数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R]，计算三个数的和 sumsumsum 判断是否满足为 000，满足则添加进结果集\n",
    "# 如果 nums[i]nums[i]nums[i]大于 000，则三数之和必然无法等于 000，结束循环\n",
    "# 如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1]，则说明该数字重复，会导致结果重复，所以应该跳过\n",
    "# 当 sumsumsum == 000 时，nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复，应该跳过，L++\n",
    "# 当 sumsumsum == 000 时，nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复，应该跳过，R−−\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         if not nums or len(nums) < 3:\n",
    "#             return []\n",
    "        \n",
    "#         ans = []\n",
    "#         nums.sort()\n",
    "#         for i in range(0, len(nums)):\n",
    "#             if nums[i] > 0: # 因为排序过，所以第一个数》0了，sum三数之和肯定大于0了\n",
    "#                 break\n",
    "#             if i > 0 and nums[i] == nums[i-1]: # 去重第一个数\n",
    "#                 continue\n",
    "            \n",
    "#             # 左右指针从两边向中间对齐\n",
    "#             l = i + 1\n",
    "#             r = len(nums) - 1\n",
    "#             while l < r:\n",
    "#                 sum = nums[i] + nums[l] + nums[r]\n",
    "#                 left = nums[l]\n",
    "#                 right = nums[r]\n",
    "#                 if sum == 0:\n",
    "#                     ans.append([nums[i], nums[l], nums[r]])\n",
    "#                     # 去重第二、第三个数\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                     # l += 1\n",
    "#                     # r -= 1\n",
    "#                 elif sum < 0:\n",
    "#                     l += 1\n",
    "#                 elif sum > 0:\n",
    "#                     r -= 1\n",
    "#         return ans\n",
    "\n",
    "\n",
    "# 方法二：labuladong 排序+双指针\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        # n 为 3，从 nums[0] 开始计算和为 0 的三元组\n",
    "        # n 填写想求的是几数之和，start 从哪个索引开始计算（一般填 0），target 填想凑出的目标和\n",
    "        ans = self.nSumTarget(nums, 3, 0, 0)\n",
    "\n",
    "        return ans\n",
    "    \n",
    "    def nSumTarget(self, nums, n, start, target):\n",
    "        if len(nums) < n:\n",
    "            return []\n",
    "        if n < 2:# 至少是2Sum\n",
    "            return []\n",
    "        \n",
    "        ans = []\n",
    "        \n",
    "        if n == 2: # 就是最好写的两数之和\n",
    "        # 双指针那一套操作\n",
    "            l, r = start, len(nums) - 1\n",
    "            while l < r:\n",
    "                sum_ = nums[l] + nums[r]\n",
    "                left, right = nums[l], nums[r]\n",
    "                if sum_ == target:\n",
    "                    ans.append([left, right])\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ > target:\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ < target:\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "        else:\n",
    "            # 大于2Sum的，先求n-1\n",
    "            # n > 2 时，递归计算 (n-1)Sum 的结果，就想象成3Sum的，比较好理解\n",
    "            for i in range(start, len(nums)):\n",
    "                if i > 0 and nums[i] == nums[i-1]: #去重\n",
    "                    continue\n",
    "\n",
    "                target_ = target - nums[i]\n",
    "                sub = self.nSumTarget(nums, n - 1, i + 1, target_)\n",
    "                for arr in sub:\n",
    "                    # (n-1)Sum 加上 nums[i] 就是 nSum\n",
    "                    arr.append(nums[i])\n",
    "                    ans.append(arr) # 这里的ans是指最外层的ans，是[]。递归时候最里层的ans被用掉了，不为空。但代码跑到这时，用的是最外层的ans，为[]\n",
    "        \n",
    "        return ans\n",
    "\n",
    "        \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "\n",
    "        def process(nums,tar):\n",
    "            i,j = 0,len(nums) - 1\n",
    "            result = []\n",
    "\n",
    "            while i < j:\n",
    "                if i > 0 and nums[i] ==nums[i - 1]:\n",
    "                    i += 1\n",
    "                    continue\n",
    "                if j < len(nums) - 1 and nums[j] == nums[j + 1]:\n",
    "                    j -= 1\n",
    "                    continue\n",
    "                cur = nums[i] + nums[j]\n",
    "                if cur > tar:\n",
    "                    j -= 1\n",
    "                elif cur < tar:\n",
    "                    i += 1\n",
    "                else:\n",
    "\n",
    "                    result.append([nums[i],nums[j],-1*tar])\n",
    "\n",
    "                    i += 1\n",
    "                    j -= 1\n",
    "            return result\n",
    "        \n",
    "        nums.sort()\n",
    "        result = []\n",
    "        last = None\n",
    "        while len(nums) > 2:\n",
    "\n",
    "            tar = nums.pop() \n",
    "            if last == tar:\n",
    "                continue\n",
    "            last = tar\n",
    "            tp = process(nums,-1*tar)\n",
    "            if tp:\n",
    "                result.extend(tp)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        res = []\n",
    "        if not nums:\n",
    "            return res\n",
    "        \n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        for i in range(n):\n",
    "            target = - nums[i]\n",
    "            hash = dict()\n",
    "            for j in range(i+1, n):\n",
    "                temp = target - nums[j]\n",
    "                if temp in hash:\n",
    "                    ans = [nums[i],nums[j], temp]\n",
    "                    # ans.sort()\n",
    "                    if ans not in res:\n",
    "                        res.append(ans)     \n",
    "                hash[nums[j]] = 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ret = []\n",
    "        for i in range(n):\n",
    "            # a + b = -c\n",
    "            if i - 1 >= 0 and nums[i] == nums[i - 1]:continue\n",
    "            target = -nums[i]\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                temp = nums[left] + nums[right]\n",
    "                if temp < target:left += 1\n",
    "                elif temp > target:right -= 1\n",
    "                else:\n",
    "                    ret.append([-target,nums[left],nums[right]])\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                    #这里也需要去重\n",
    "                    while left < right and nums[left] == nums[left - 1]:left += 1\n",
    "                    while left < right and nums[right] == nums[right + 1]:right -= 1\n",
    "        return ret\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def twosum(nums,start,target):\n",
    "    res = []\n",
    "    left,right = start,len(nums)-1\n",
    "    while left < right:\n",
    "        left_num, right_num = nums[left], nums[right]\n",
    "        two_sum = left_num + right_num\n",
    "        if two_sum > target:\n",
    "            right -= 1\n",
    "            while left < right and nums[right] == right_num:\n",
    "                right -= 1\n",
    "        elif two_sum < target:\n",
    "            left += 1\n",
    "            while left < right and nums[left] == left_num:\n",
    "                left += 1\n",
    "        elif two_sum == target:\n",
    "            res.append([nums[left],nums[right]])\n",
    "            while left < right and nums[left] == left_num:\n",
    "                left += 1\n",
    "            while left < right and nums[right] == right_num:\n",
    "                right -= 1\n",
    "    return res\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        output = []\n",
    "        i = 0\n",
    "        while i < len(nums):\n",
    "            temp_res = twosum(nums,i+1,0-nums[i])\n",
    "\n",
    "            for item in temp_res:\n",
    "                item.append(nums[i])\n",
    "                output.append(item)\n",
    "            while i < len(nums) - 1 and nums[i] == nums[i + 1]:\n",
    "                i += 1\n",
    "            i += 1\n",
    "        return output\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        s = {}\n",
    "        for num in nums:\n",
    "            if num in s.keys():\n",
    "                s[num] += 1\n",
    "            else:\n",
    "                s[num] = 1\n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            if s[nums[i]] == 0:\n",
    "                continue\n",
    "            s[nums[i]] -= 1\n",
    "            s_tmp = s.copy()\n",
    "            for j in range(i+1,n):\n",
    "                if s_tmp[nums[j]] == 0:\n",
    "                    continue\n",
    "                s_tmp[nums[j]] -= 1\n",
    "                target = (0-nums[i]-nums[j])\n",
    "                if s_tmp.get(target, 0) > 0:\n",
    "                    res.append([nums[i], nums[j], target])\n",
    "                s_tmp[nums[j]] = 0\n",
    "            s[nums[i]] = 0\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 方法一\n",
    "# 标签：数组遍历\n",
    "# 首先对数组进行排序，排序后固定一个数 nums[i]nums[i]nums[i]，再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端，数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R]，计算三个数的和 sumsumsum 判断是否满足为 000，满足则添加进结果集\n",
    "# 如果 nums[i]nums[i]nums[i]大于 000，则三数之和必然无法等于 000，结束循环\n",
    "# 如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1]，则说明该数字重复，会导致结果重复，所以应该跳过\n",
    "# 当 sumsumsum == 000 时，nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复，应该跳过，L++\n",
    "# 当 sumsumsum == 000 时，nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复，应该跳过，R−−\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         if not nums or len(nums) < 3:\n",
    "#             return []\n",
    "        \n",
    "#         ans = []\n",
    "#         nums.sort()\n",
    "#         for i in range(0, len(nums)):\n",
    "#             if nums[i] > 0: # 因为排序过，所以第一个数》0了，sum三数之和肯定大于0了\n",
    "#                 break\n",
    "#             if i > 0 and nums[i] == nums[i-1]: # 去重第一个数\n",
    "#                 continue\n",
    "            \n",
    "#             # 左右指针从两边向中间对齐\n",
    "#             l = i + 1\n",
    "#             r = len(nums) - 1\n",
    "#             while l < r:\n",
    "#                 sum = nums[i] + nums[l] + nums[r]\n",
    "#                 left = nums[l]\n",
    "#                 right = nums[r]\n",
    "#                 if sum == 0:\n",
    "#                     ans.append([nums[i], nums[l], nums[r]])\n",
    "#                     # 去重第二、第三个数\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                     # l += 1\n",
    "#                     # r -= 1\n",
    "#                 elif sum < 0:\n",
    "#                     l += 1\n",
    "#                 elif sum > 0:\n",
    "#                     r -= 1\n",
    "#         return ans\n",
    "\n",
    "\n",
    "# 方法二：labuladong 排序+双指针\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        # n 为 3，从 nums[0] 开始计算和为 0 的三元组\n",
    "        # n 填写想求的是几数之和，start 从哪个索引开始计算（一般填 0），target 填想凑出的目标和\n",
    "        ans = self.nSumTarget(nums, 3, 0, 0)\n",
    "\n",
    "        return ans\n",
    "    \n",
    "    def nSumTarget(self, nums, n, start, target):\n",
    "        if len(nums) < n:\n",
    "            return []\n",
    "        if n < 2:# 至少是2Sum\n",
    "            return []\n",
    "        \n",
    "        ans = []\n",
    "        l, r = start, len(nums) - 1\n",
    "        if n == 2: # 就是最好写的两数之和\n",
    "            while l < r:\n",
    "                sum_ = nums[l] + nums[r]\n",
    "                left, right = nums[l], nums[r]\n",
    "                if sum_ == target:\n",
    "                    ans.append([left, right])\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ > target:\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ < target:\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "        else:\n",
    "            # 大于2Sum的，先求n-1\n",
    "            # n > 2 时，递归计算 (n-1)Sum 的结果，就想象成3Sum的，比较好理解\n",
    "            for i in range(start, len(nums)):\n",
    "                if i > 0 and nums[i] == nums[i-1]: #去重\n",
    "                    continue\n",
    "\n",
    "                target_ = target - nums[i]\n",
    "                sub = self.nSumTarget(nums, n - 1, i + 1, target_)\n",
    "                for arr in sub:\n",
    "                    arr.append(nums[i])\n",
    "                    ans.append(arr)\n",
    "        \n",
    "        return ans\n",
    "\n",
    "        \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 方法一\n",
    "# 标签：数组遍历\n",
    "# 首先对数组进行排序，排序后固定一个数 nums[i]nums[i]nums[i]，再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端，数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R]，计算三个数的和 sumsumsum 判断是否满足为 000，满足则添加进结果集\n",
    "# 如果 nums[i]nums[i]nums[i]大于 000，则三数之和必然无法等于 000，结束循环\n",
    "# 如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1]，则说明该数字重复，会导致结果重复，所以应该跳过\n",
    "# 当 sumsumsum == 000 时，nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复，应该跳过，L++\n",
    "# 当 sumsumsum == 000 时，nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复，应该跳过，R−−\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         if not nums or len(nums) < 3:\n",
    "#             return []\n",
    "        \n",
    "#         ans = []\n",
    "#         nums.sort()\n",
    "#         for i in range(0, len(nums)):\n",
    "#             if nums[i] > 0: # 因为排序过，所以第一个数》0了，sum三数之和肯定大于0了\n",
    "#                 break\n",
    "#             if i > 0 and nums[i] == nums[i-1]: # 去重第一个数\n",
    "#                 continue\n",
    "            \n",
    "#             # 左右指针从两边向中间对齐\n",
    "#             l = i + 1\n",
    "#             r = len(nums) - 1\n",
    "#             while l < r:\n",
    "#                 sum = nums[i] + nums[l] + nums[r]\n",
    "#                 left = nums[l]\n",
    "#                 right = nums[r]\n",
    "#                 if sum == 0:\n",
    "#                     ans.append([nums[i], nums[l], nums[r]])\n",
    "#                     # 去重第二、第三个数\n",
    "#                     while l < r and nums[l] == left:\n",
    "#                         l += 1\n",
    "#                     while l < r and nums[r] == right:\n",
    "#                         r -= 1\n",
    "#                     # l += 1\n",
    "#                     # r -= 1\n",
    "#                 elif sum < 0:\n",
    "#                     l += 1\n",
    "#                 elif sum > 0:\n",
    "#                     r -= 1\n",
    "#         return ans\n",
    "\n",
    "\n",
    "# 方法二：labuladong 排序+双指针\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        # n 为 3，从 nums[0] 开始计算和为 0 的三元组\n",
    "        # n 填写想求的是几数之和，start 从哪个索引开始计算（一般填 0），target 填想凑出的目标和\n",
    "        ans = self.nSumTarget(nums, 3, 0, 0)\n",
    "\n",
    "        return ans\n",
    "    \n",
    "    def nSumTarget(self, nums, n, start, target):\n",
    "        if len(nums) < n:\n",
    "            return []\n",
    "        if n < 2:# 至少是2Sum\n",
    "            return []\n",
    "        \n",
    "        ans = []\n",
    "        \n",
    "        if n == 2: # 就是最好写的两数之和\n",
    "        # 双指针那一套操作\n",
    "            l, r = start, len(nums) - 1\n",
    "            while l < r:\n",
    "                sum_ = nums[l] + nums[r]\n",
    "                left, right = nums[l], nums[r]\n",
    "                if sum_ == target:\n",
    "                    ans.append([left, right])\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ > target:\n",
    "                    while l < r and nums[r] == right:\n",
    "                        r -= 1\n",
    "                elif sum_ < target:\n",
    "                    while l < r and nums[l] == left:\n",
    "                        l += 1\n",
    "        else:\n",
    "            # 大于2Sum的，先求n-1\n",
    "            # n > 2 时，递归计算 (n-1)Sum 的结果，就想象成3Sum的，比较好理解\n",
    "            for i in range(start, len(nums)):\n",
    "                if i > 0 and nums[i] == nums[i-1]: #去重\n",
    "                    continue\n",
    "\n",
    "                target_ = target - nums[i]\n",
    "                sub = self.nSumTarget(nums, n - 1, i + 1, target_)\n",
    "                for arr in sub:\n",
    "                    # (n-1)Sum 加上 nums[i] 就是 nSum\n",
    "                    arr.append(nums[i])\n",
    "                    ans.append(arr) # 这里的ans是指最外层的ans，是[]。递归时候最里层的ans被用掉了，不为空。但代码跑到这时，用的是最外层的ans，为[]\n",
    "        \n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        '''\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        def find(l,r,target):\n",
    "            if l>r:\n",
    "                return r\n",
    "            now = (l+r) // 2\n",
    "            if nums[now] == target:\n",
    "                return now\n",
    "            if nums[now] < target:\n",
    "                return find(now+1,r,target)\n",
    "            if nums[now] > target:\n",
    "                return find(l,now-1,target)\n",
    "        res = []\n",
    "        i = 0\n",
    "        while(i<n-2):\n",
    "            if nums[i] + nums[i+1] + nums[i+2] > 0:\n",
    "                break\n",
    "            r = n-1\n",
    "            j = i+1\n",
    "            while(j<n-1):\n",
    "                target = 0-(nums[i]+nums[j])\n",
    "                l = j+1\n",
    "                if nums[l] > target:\n",
    "                    break\n",
    "                if nums[r] >= target and nums[l] <= target and l<=r:\n",
    "                    r = find(l,r,target)\n",
    "                    if nums[r] == target:\n",
    "                        res.append([nums[i],nums[j],nums[r]])\n",
    "                        r -= 1\n",
    "                j += 1\n",
    "                while(j<n and nums[j-1]==nums[j]):\n",
    "                    j += 1\n",
    "            i += 1\n",
    "            while(i<n and nums[i-1]==nums[i]):\n",
    "                i += 1\n",
    "        return res    \n",
    "        '''\n",
    "        n = len(nums)\n",
    "        if n == 0:\n",
    "            return []\n",
    "        nums.sort()\n",
    "        s = {}\n",
    "        pre_num = nums[0]\n",
    "        count = 1\n",
    "        for num in nums[1:]:\n",
    "            if pre_num == num:\n",
    "                count += 1\n",
    "            else:\n",
    "                s[pre_num] = count\n",
    "                pre_num = num\n",
    "                count = 1\n",
    "        s[pre_num] = count\n",
    "\n",
    "        res = []\n",
    "        i = 0\n",
    "        while(i<n-2):\n",
    "            if nums[i] + nums[i+1] + nums[i+2] > 0:\n",
    "                break\n",
    "            s[nums[i]] -= 1\n",
    "            s_tmp = s.copy()\n",
    "            j = i+1\n",
    "            while(j<n-1):\n",
    "                if nums[i] + nums[j] + nums[j+1] > 0:\n",
    "                    break \n",
    "                s_tmp[nums[j]] -= 1\n",
    "                target = (0-nums[i]-nums[j])\n",
    "                if s_tmp.get(target, 0) > 0:\n",
    "                    res.append([nums[i], nums[j], target])\n",
    "                s_tmp[nums[j]] = 0\n",
    "                j += 1\n",
    "                while(j<n and nums[j-1]==nums[j]):\n",
    "                    j += 1\n",
    "            s[nums[i]] = 0\n",
    "            i += 1\n",
    "            while(i<n and nums[i-1]==nums[i]):\n",
    "                i += 1\n",
    "\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "\n",
    "        def process(nums,tar):\n",
    "            i,j = 0,len(nums) - 1\n",
    "            result = []\n",
    "            hashmap = set()\n",
    "            while i < j:\n",
    "                if nums[i] in hashmap:\n",
    "                    i += 1\n",
    "                    continue\n",
    "                if nums[j] in hashmap:\n",
    "                    j -= 1\n",
    "                    continue\n",
    "\n",
    "                cur = nums[i] + nums[j]\n",
    "                if cur > tar:\n",
    "                    j -= 1\n",
    "                elif cur < tar:\n",
    "                    i += 1\n",
    "                else:\n",
    "                    if nums[i] not in hashmap or nums[j] not in hashmap:\n",
    "                        result.append([nums[i],nums[j],-1*tar])\n",
    "                        hashmap.add(nums[i])\n",
    "                        hashmap.add(nums[j])\n",
    "                    i += 1\n",
    "                    j -= 1\n",
    "            return result\n",
    "        \n",
    "        nums.sort()\n",
    "        result = []\n",
    "        hashmap = set()\n",
    "        while len(nums) > 2:\n",
    "            tar = nums.pop()\n",
    "            if tar in hashmap:\n",
    "                continue\n",
    "            hashmap.add(tar)\n",
    "            tp = process(nums,-1*tar)\n",
    "            if tp:\n",
    "                result.extend(tp)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        str_set = set()\n",
    "        ans = []\n",
    "        for i in range(len(nums)-2):\n",
    "            num = nums[i]\n",
    "            num_dict = {}\n",
    "            for j in range(i+1, len(nums)):\n",
    "                if -(nums[j] + nums[i]) in num_dict:\n",
    "                    seq = [nums[j], nums[i], -(nums[i]+nums[j])]\n",
    "                    seq.sort()\n",
    "                    if str(seq) not in str_set:\n",
    "                        ans.append(seq)\n",
    "                        str_set.add(str(seq))\n",
    "                num_dict[nums[j]] = j\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ans = []\n",
    "        nums_map = {value: index for index, value in enumerate(nums)}\n",
    "\n",
    "        for i in range(n):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            for j in range(i + 1, n):\n",
    "                if j > i + 1 and nums[j] == nums[j - 1]:\n",
    "                    continue\n",
    "                val = - (nums[j] + nums[i])\n",
    "                if val in nums_map and nums_map[val] > j:\n",
    "                    ans.append([nums[i], nums[j], val])\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        '''\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        def find(l,r,target):\n",
    "            if l>r:\n",
    "                return r\n",
    "            now = (l+r) // 2\n",
    "            if nums[now] == target:\n",
    "                return now\n",
    "            if nums[now] < target:\n",
    "                return find(now+1,r,target)\n",
    "            if nums[now] > target:\n",
    "                return find(l,now-1,target)\n",
    "        res = []\n",
    "        i = 0\n",
    "        while(i<n-2):\n",
    "            r = n-1\n",
    "            j = i+1\n",
    "            while(j<n-1):\n",
    "                target = 0-(nums[i]+nums[j])\n",
    "                l = j+1\n",
    "                if nums[r] >= target and nums[l] <= target and l<=r:\n",
    "                    r = find(l,r,target)\n",
    "                    if nums[r] == target:\n",
    "                        res.append([nums[i],nums[j],nums[r]])\n",
    "                        r -= 1\n",
    "                j += 1\n",
    "                while(j<n and nums[j-1]==nums[j]):\n",
    "                    j += 1\n",
    "            i += 1\n",
    "            while(i<n and nums[i-1]==nums[i]):\n",
    "                i += 1\n",
    "        return res    \n",
    "        '''\n",
    "        n = len(nums)\n",
    "        s = {}\n",
    "        for num in nums:\n",
    "            if num in s.keys():\n",
    "                s[num] += 1\n",
    "            else:\n",
    "                s[num] = 1\n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            if s[nums[i]] == 0:\n",
    "                continue\n",
    "            s[nums[i]] -= 1\n",
    "            s_tmp = s.copy()\n",
    "            for j in range(i+1,n):\n",
    "                if s_tmp[nums[j]] == 0:\n",
    "                    continue\n",
    "                s_tmp[nums[j]] -= 1\n",
    "                target = (0-nums[i]-nums[j])\n",
    "                if s_tmp.get(target, 0) > 0:\n",
    "                    res.append([nums[i], nums[j], target])\n",
    "                s_tmp[nums[j]] = 0\n",
    "            s[nums[i]] = 0\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans=set()\n",
    "        for i in range(len(nums)-2):\n",
    "            if nums[i]>0:break\n",
    "            for j in range(i+1,len(nums)-1):\n",
    "                num = nums[i]+nums[j]\n",
    "                m=j+1\n",
    "                n=len(nums)\n",
    "                while m<n:\n",
    "                    mid = ((n-m)>>1)+m\n",
    "                    if -num == nums[mid]:\n",
    "                        ans.add((nums[i],nums[j],nums[mid]))\n",
    "                        break\n",
    "                    if -num > nums[mid]:\n",
    "                        m=mid+1\n",
    "                    else:\n",
    "                        n=mid\n",
    "        return [list(i) for i in ans]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def dfs(self, used, nums, ind, current, ans, h):\n",
    "        if len(current) == 2:\n",
    "            lacked = -sum(current)\n",
    "            if lacked in h:\n",
    "                ind_left = h[lacked]\n",
    "                if ind_left >= ind:\n",
    "                    current += [nums[ind_left]]\n",
    "                    ans.append(current)\n",
    "            return\n",
    "\n",
    "        current_sum = sum(current)\n",
    "        for i, num in enumerate(nums[ind:]):\n",
    "            if used[i+ind] == 1:\n",
    "                continue\n",
    "            elif i+ind > 0 and nums[i+ind-1] == num and used[i+ind-1] == 0: \n",
    "                continue\n",
    "            elif sum(nums[i+ind:i+ind+(3-len(current))]) + current_sum > 0:\n",
    "                break\n",
    "            elif sum(nums[len(current)-3:]) + current_sum < 0:\n",
    "                break\n",
    "            else:\n",
    "                used[i+ind] = 1\n",
    "                self.dfs(used, nums, i+ind+1, current+[num], ans, h)\n",
    "                used[i+ind] = 0\n",
    "        return\n",
    "\n",
    "    def twoSum(self, nums, target, ans):\n",
    "        si = 0\n",
    "        ei = len(nums)\n",
    "        while si < ei-1:\n",
    "            if nums[si] + nums[ei-1] < target:\n",
    "                si += 1\n",
    "            elif nums[si] + nums[ei-1] > target:\n",
    "                ei -= 1\n",
    "            else:\n",
    "                ans.append([-target, nums[si], nums[ei-1]])\n",
    "                si += 1\n",
    "                while si < ei and nums[si-1] == nums[si] :\n",
    "                    si += 1\n",
    "        return \n",
    "\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        for i, num in enumerate(nums[:-2]):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            if -num <= 2 * nums[-1] and -num >= 2 * nums[i+1]:\n",
    "                self.twoSum(nums[i+1:], -num, ans)\n",
    "        return ans\n",
    "        # nums.sort()\n",
    "        # si = 0\n",
    "        # ei = len(nums)-1\n",
    "        # # h = {n:i for i,n in enumerate(nums)}\n",
    "        # num2ind = {}\n",
    "        # ans = []\n",
    "        # for i, n in enumerate(nums):\n",
    "        #     if n not in num2ind:\n",
    "        #         num2ind[n] = i\n",
    "        \n",
    "        # while si + 1 < ei:\n",
    "        #     lacked = 0 - nums[ei] - nums[si]\n",
    "        #     if lacked in num2ind:\n",
    "        #         ans.append([nums[si], nums[num2ind[lacked]], nums[ei]])\n",
    "                \n",
    "        #     else:\n",
    "        #         if nums[si] + nums[ei-1] + nums[ei] < 0:\n",
    "        #             while nums[si] == nums[si+1] and si < ei:\n",
    "        #                 si += 1\n",
    "        #         elif nums[si] + nums[si+1] + nums[ei] > 0:\n",
    "        #             while nums[ei] == nums[ei-1] and si < ei:\n",
    "        #                 ei -= 1\n",
    "        #         else:\n",
    "        #             si += 1\n",
    "        # return ans\n",
    "\n",
    "\n",
    "    def threeSum1(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        h = {n:i for i,n in enumerate(nums)}\n",
    "        ans = []\n",
    "        current = []\n",
    "\n",
    "        used = [0] * len(nums)\n",
    "        self.dfs(used, nums, 0, current, ans, h)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)       \n",
    "        nums.sort()\n",
    "        # res = []\n",
    "        ans = set()\n",
    "        for i in range(n-2):\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                sum = nums[i] + nums[left] + nums[right]\n",
    "                    # res.append([nums[i],nums[left],nums[right]])\n",
    "                if sum < 0:\n",
    "                    left += 1\n",
    "                elif sum > 0:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    ans.add((nums[i],nums[left],nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1                    \n",
    "        return [list(a) for a in ans]\n",
    "                \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def dfs(self, used, nums, ind, current, ans, h):\n",
    "        if len(current) == 2:\n",
    "            # print(current)\n",
    "            lacked = -sum(current)\n",
    "            if lacked in h:\n",
    "                ind_left = h[lacked]\n",
    "                if ind_left >= ind:\n",
    "                    current += [nums[ind_left]]\n",
    "                    ans.append(current)\n",
    "            return\n",
    "\n",
    "        current_sum = sum(current)\n",
    "        for i, num in enumerate(nums[ind:]):\n",
    "            if used[i+ind] == 1:\n",
    "                continue\n",
    "            elif i+ind > 0 and nums[i+ind-1] == num and used[i+ind-1] == 0: \n",
    "                continue\n",
    "            elif sum(nums[i+ind:i+ind+(3-len(current))]) + current_sum > 0:\n",
    "                # print(\"to large\")\n",
    "                break\n",
    "            elif sum(nums[len(current)-3:]) + current_sum < 0:\n",
    "                # print(\"to small\")\n",
    "                break\n",
    "            else:\n",
    "                used[i+ind] = 1\n",
    "                self.dfs(used, nums, i+ind+1, current+[num], ans, h)\n",
    "                used[i+ind] = 0\n",
    "        return\n",
    "\n",
    "\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        # sorted(nums)\n",
    "        nums.sort()\n",
    "        # print(nums)\n",
    "        h = {n:i for i,n in enumerate(nums)}\n",
    "        ans = []\n",
    "        current = []\n",
    "\n",
    "        used = [0] * len(nums)\n",
    "        self.dfs(used, nums, 0, current, ans, h)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums=sorted(nums)\n",
    "        n=len(nums)\n",
    "        res=set()\n",
    "        for i in range(n-2):\n",
    "            k=n-1\n",
    "            for j in range(i+1,n-1):\n",
    "                while nums[i]+nums[j]+nums[k]>=0 and j<k:\n",
    "                    if nums[i]+nums[j]+nums[k]==0:\n",
    "                        res.add((nums[i],nums[j],nums[k]))\n",
    "                    k-=1\n",
    "                if j>=k:\n",
    "                    break\n",
    "        return [list(result) for result in res]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = set()\n",
    "        n = len(nums)\n",
    "        for i in range(n - 2):\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            x = nums[i]\n",
    "            while j < k:\n",
    "                cur = x + nums[j] + nums[k]\n",
    "                if cur > 0:\n",
    "                    k -= 1\n",
    "                elif cur < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    ans.add((x, nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "        return [list(a) for a in ans]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        #1e3 1e6<1e8\n",
    "\n",
    "        result=[]\n",
    "        r=set()\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            end=len(nums)-1\n",
    "            start=i+1\n",
    "            while start<end:\n",
    "                if nums[start]+nums[end]+nums[i]>0:\n",
    "                    end-=1\n",
    "                elif nums[start]+nums[end]+nums[i]<0:\n",
    "                    start+=1\n",
    "                elif nums[start]+nums[end]+nums[i]==0:\n",
    "                    if (nums[i],nums[start],nums[end]) not in r:\n",
    "                        result.append([nums[i],nums[start],nums[end]])\n",
    "                        r.add((nums[i],nums[start],nums[end]))\n",
    "                    start+=1\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        start = 0\n",
    "        res_set = set()\n",
    "        for start in range(n - 2):\n",
    "            left = start + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                cur_sum = nums[start] + nums[left] + nums[right]\n",
    "                if cur_sum == 0:\n",
    "                    res_set.add((nums[start], nums[left], nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif cur_sum > 0:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left += 1\n",
    "        res = [list(x) for x in res_set]\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        # 排序\n",
    "        arr = sorted(nums)\n",
    "        res = []\n",
    "        nums_dict = dict()\n",
    "        # 遍历数组,\n",
    "        for i, num in enumerate(arr):\n",
    "            # 双指针判断是否存在两个数之和是 -num 的两个数存在\n",
    "            left, right = i + 1, len(arr) - 1\n",
    "            while left < right:\n",
    "                if arr[left] + arr[right] == -num:\n",
    "                    # 先判断是都在元组字典，不在添加res.更新元组\n",
    "                    if (num, arr[left], arr[right]) not in nums_dict:\n",
    "                        res.append([num, arr[left], arr[right]])\n",
    "                        nums_dict.update({(num, arr[left], arr[right]) :1})\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif arr[left] + arr[right] < -num:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        rs = set()\n",
    "        n = len(nums)\n",
    "        for idx,val in enumerate(nums):\n",
    "            if val == 0 and idx+2 < n and nums[idx+2] == 0:\n",
    "                rs.add((0,0,0))\n",
    "                continue\n",
    "            \n",
    "            target = -val\n",
    "            l,r = idx+1,n-1\n",
    "            while l < r:\n",
    "                s = nums[l]+nums[r]\n",
    "                if s == target:\n",
    "                    rs.add((val,nums[l],nums[r]))\n",
    "                    l += 1\n",
    "                elif s < target:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1 \n",
    "        return [[a,b,c] for (a,b,c) in rs]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        \n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        firstnum_set = set()\n",
    "        ans_set = set()\n",
    "        for i in range(len(nums) - 2):\n",
    "            base = nums[i]\n",
    "            firstnum_set.add(base)\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            target = 0 - base\n",
    "\n",
    "            while left < right:\n",
    "                if nums[left] + nums[right] == target:\n",
    "                    if (base,nums[left],nums[right]) not in ans_set:\n",
    "                        ans.append([base,nums[left],nums[right]])\n",
    "                        ans_set.add((base,nums[left],nums[right]))\n",
    "                \n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif nums[left] + nums[right] < target:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        ans = set()\n",
    "\n",
    "        for i in range(n):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            while j < k:\n",
    "                tmp = nums[i] + nums[j] + nums[k]\n",
    "                if tmp == 0:\n",
    "                    ans.add((nums[i], nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                elif tmp < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    k -= 1\n",
    "\n",
    "        # ans = list(ans)\n",
    "\n",
    "        return [list(a) for a in ans]\n",
    "\n",
    "\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        for i, num in enumerate(nums):\n",
    "            if i > 0 and nums[i] == nums[i-1]: continue\n",
    "            target = -num\n",
    "            dic = dict()\n",
    "            for j in range(i+1, len(nums)):\n",
    "                #if j > i+1 and nums[j] == nums[j-1]: continue\n",
    "                if target - nums[j] in dic:\n",
    "                    res.append([nums[i], nums[dic[target-nums[j]]], nums[j]])\n",
    "                else:\n",
    "                    dic[nums[j]] = j\n",
    "        res = list(sorted(l) for l in res)\n",
    "        res = list(set([tuple(t) for t in res]))\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = set()\n",
    "        n = len(nums)\n",
    "        for i in range(n - 2):\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            x = nums[i]\n",
    "            while j < k:\n",
    "                cur = x + nums[j] + nums[k]\n",
    "                if cur > 0:\n",
    "                    k -= 1\n",
    "                elif cur < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    ans.add((x, nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "        return [list(a) for a in ans]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        reapt = []\n",
    "        self.tup = []\n",
    "        for i,x in enumerate(nums):\n",
    "            if x not in reapt:\n",
    "                reapt.append(x)\n",
    "                self.tup = self.tup + self.twosum(i,-x,nums)\n",
    "        return self.tup\n",
    "\n",
    "\n",
    "    def twosum(self, index, target, nums):\n",
    "        m = {}\n",
    "        tup1 = []\n",
    "        nums = nums[index+1:]\n",
    "        for i,x in enumerate(nums):\n",
    "            # nums1 = nums.copy()\n",
    "            # nums1.pop(i)\n",
    "            #nums1 = nums[i+1:] \n",
    "            if target-x in m:\n",
    "                temp = [-target, x,target-x]\n",
    "                temp.sort()\n",
    "                if temp not in tup1 and temp not in self.tup:\n",
    "                    tup1.append(temp)\n",
    "            m[x] = i\n",
    "        return tup1\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         n = len(nums)\n",
    "#         nums.sort()\n",
    "#         ans = list()\n",
    "        \n",
    "#         # 枚举 a\n",
    "#         for first in range(n):\n",
    "#             # 需要和上一次枚举的数不相同\n",
    "#             if first > 0 and nums[first] == nums[first - 1]:\n",
    "#                 continue\n",
    "#             # c 对应的指针初始指向数组的最右端\n",
    "#             third = n - 1\n",
    "#             target = -nums[first]\n",
    "#             # 枚举 b\n",
    "#             for second in range(first + 1, n):\n",
    "#                 # 需要和上一次枚举的数不相同\n",
    "#                 if second > first + 1 and nums[second] == nums[second - 1]:\n",
    "#                     continue\n",
    "#                 # 需要保证 b 的指针在 c 的指针的左侧\n",
    "#                 while second < third and nums[second] + nums[third] > target:\n",
    "#                     third -= 1\n",
    "#                 # 如果指针重合，随着 b 后续的增加\n",
    "#                 # 就不会有满足 a+b+c=0 并且 b<c 的 c 了，可以退出循环\n",
    "#                 if second == third:\n",
    "#                     break\n",
    "#                 if nums[second] + nums[third] == target:\n",
    "#                     ans.append([nums[first], nums[second], nums[third]])\n",
    "        \n",
    "#         return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        tmp = {}\n",
    "        for i in range(len(nums)):\n",
    "            l = i-1\n",
    "            r = i+1\n",
    "            while l >= 0 and r < len(nums):\n",
    "                s = nums[l] + nums[i] + nums[r]\n",
    "                tmpl = nums[l]\n",
    "                tmpr = nums[r]\n",
    "                if s == 0:\n",
    "                    if str([nums[l], nums[i], nums[r]]) not in tmp:\n",
    "                        tmp[str([nums[l], nums[i], nums[r]])] = True\n",
    "                        res.append([nums[l], nums[i], nums[r]])\n",
    "                    r += 1\n",
    "                    l -= 1\n",
    "                elif s < 0:\n",
    "                    r += 1\n",
    "                else:\n",
    "                    l -= 1\n",
    "        return res\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        reapt = []\n",
    "        self.tup = []\n",
    "        for i,x in enumerate(nums):\n",
    "            if x not in reapt:\n",
    "                reapt.append(x)\n",
    "                self.tup = self.tup + self.twosum(i,-x,nums)\n",
    "        return self.tup\n",
    "\n",
    "\n",
    "    def twosum(self, index, target, nums):\n",
    "        m = {}\n",
    "        tup1 = []\n",
    "        for i,x in enumerate(nums[index+1:]):\n",
    "            if target-x in m:\n",
    "                temp = [-target, x,target-x]\n",
    "                temp.sort()\n",
    "                if temp not in tup1 and temp not in self.tup:\n",
    "                    tup1.append(temp)\n",
    "            m[x] = i\n",
    "        return tup1\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "#         n = len(nums)\n",
    "#         nums.sort()\n",
    "#         ans = list()\n",
    "        \n",
    "#         # 枚举 a\n",
    "#         for first in range(n):\n",
    "#             # 需要和上一次枚举的数不相同\n",
    "#             if first > 0 and nums[first] == nums[first - 1]:\n",
    "#                 continue\n",
    "#             # c 对应的指针初始指向数组的最右端\n",
    "#             third = n - 1\n",
    "#             target = -nums[first]\n",
    "#             # 枚举 b\n",
    "#             for second in range(first + 1, n):\n",
    "#                 # 需要和上一次枚举的数不相同\n",
    "#                 if second > first + 1 and nums[second] == nums[second - 1]:\n",
    "#                     continue\n",
    "#                 # 需要保证 b 的指针在 c 的指针的左侧\n",
    "#                 while second < third and nums[second] + nums[third] > target:\n",
    "#                     third -= 1\n",
    "#                 # 如果指针重合，随着 b 后续的增加\n",
    "#                 # 就不会有满足 a+b+c=0 并且 b<c 的 c 了，可以退出循环\n",
    "#                 if second == third:\n",
    "#                     break\n",
    "#                 if nums[second] + nums[third] == target:\n",
    "#                     ans.append([nums[first], nums[second], nums[third]])\n",
    "        \n",
    "#         return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        # 如果是已经排序好的话，则时间复杂度位 O(n^2)\n",
    "        def twosum(nums, start, target):\n",
    "            left, right = start, len(nums) - 1\n",
    "            lr_list = []\n",
    "            while left < right:\n",
    "                sumval = nums[left] + nums[right]\n",
    "                if sumval == target:\n",
    "                    lr_list.append([left, right])\n",
    "                    right -= 1\n",
    "                elif sumval > target:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left += 1\n",
    "            return lr_list\n",
    "        nums.sort()\n",
    "        flagSet = set()\n",
    "        result = []\n",
    "        N = len(nums)\n",
    "        for i in range(N-2):\n",
    "            target = 0 - nums[i]\n",
    "            lr_list = twosum(nums, i+1, target)\n",
    "            if len(lr_list) != 0:\n",
    "                for lr in lr_list:\n",
    "                    lstr = str([nums[i], nums[lr[0]], nums[lr[1]]])\n",
    "                    if lstr not in flagSet:\n",
    "                        result.append([nums[i], nums[lr[0]], nums[lr[1]]])\n",
    "                        flagSet.add(lstr)\n",
    "        return result\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        result = set()\n",
    "        nums.sort()\n",
    "        for index, num in enumerate(nums):\n",
    "            start, end = index + 1, len(nums) - 1\n",
    "            target = -num\n",
    "            while start < end:\n",
    "                if nums[start] + nums[end] == target:\n",
    "                    result.add(tuple(sorted([nums[start], nums[end], num])))\n",
    "                    start += 1\n",
    "                    end -= 1\n",
    "                elif nums[start] + nums[end] < target:\n",
    "                    start += 1\n",
    "                else:\n",
    "                    end -= 1\n",
    "        result = [list(res) for res in result]\n",
    "        return list(result)\n",
    "\n",
    "\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        dic={}\n",
    "        if len(nums)<3:\n",
    "            return sum(nums)\n",
    "        \n",
    "        nums.sort()\n",
    "        for i in range(len(nums)-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1\n",
    "            while l < r:\n",
    "                sum = nums[i] + nums[l] + nums[r]\n",
    "                if sum < target:\n",
    "                    l += 1\n",
    "                    dic[sum] = target - sum\n",
    "                elif sum > target:\n",
    "                    r -= 1\n",
    "                    dic[sum] = sum - target\n",
    "                else:\n",
    "                    return target\n",
    "        return min(dic,key=dic.get)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        result = 0\n",
    "        if not nums:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        tmp = float(\"inf\")\n",
    "        for i in range(len(nums) - 2):\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            lo = i + 1\n",
    "            hi = len(nums) - 1\n",
    "            while lo < hi:\n",
    "                s = nums[i] + nums[lo] + nums[hi]\n",
    "                if abs(s - target) < tmp:\n",
    "                    result = s\n",
    "                    tmp = abs(s - target)\n",
    "                if s < target:\n",
    "                    lo += 1\n",
    "                elif s > target:\n",
    "                    hi -= 1\n",
    "                else:\n",
    "                    return target\n",
    "        return result\n",
    "\n",
    "                    \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "\n",
    "        nums = sorted(nums)\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        i = 0\n",
    "        sum_num = nums[i] + nums[i + 1] + nums[i + 2]\n",
    "        closest = sum_num - target\n",
    "        while i < len(nums) - 2:\n",
    "            j = i + 1\n",
    "            k = len(nums) - 1\n",
    "\n",
    "            while j < k:\n",
    "                sum_num = nums[i] + nums[j] + nums[k]\n",
    "                close = sum_num - target\n",
    "\n",
    "                if close < 0:\n",
    "                    if abs(close) < abs(closest):\n",
    "                        closest = close\n",
    "                    j += 1\n",
    "                elif close > 0:\n",
    "                    if abs(close) < abs(closest):\n",
    "                        closest = close\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    return target\n",
    "            i += 1\n",
    "            while i < len(nums) and nums[i - 1] == nums[i]:\n",
    "                i += 1\n",
    "\n",
    "        return closest + target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        diffList = []\n",
    "        nums.sort()\n",
    "        result = ''\n",
    "        for i in range(len(nums)-2):\n",
    "            j = i + 1\n",
    "            k = len(nums) - 1\n",
    "            while j < k:\n",
    "                diff = nums[i] + nums[j] + nums[k]\n",
    "                diffList.append(diff)\n",
    "                if diff > target:\n",
    "                    k -= 1\n",
    "                elif diff < target:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    result = diff\n",
    "                    break\n",
    "            if result == diff:\n",
    "                break\n",
    "        else:\n",
    "            diffList = list(set(diffList))\n",
    "            item = [abs(x-target) for x in diffList]\n",
    "            result = diffList[item.index(min(item))]\n",
    "        return result      "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        nums.sort()\n",
    "        result,max_mm = 0,float('inf')\n",
    "        i = 0\n",
    "        while i < len(nums)-2:\n",
    "            if i == 0 or nums[i] != nums[i-1]:\n",
    "                j,k = i + 1, len(nums) - 1\n",
    "                while j < k:\n",
    "                    mm = nums[i] + nums[j] + nums[k] - target\n",
    "                    if abs(mm)<max_mm:\n",
    "                        max_mm = abs(mm)\n",
    "                        result = nums[i] + nums[j] + nums[k]\n",
    "                    if mm < 0:\n",
    "                        j += 1\n",
    "                    elif mm > 0:\n",
    "                        k -= 1\n",
    "                    else:\n",
    "                        return target\n",
    "            i += 1\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums)<3:\n",
    "            return 0\n",
    "        if len(nums) == 3:\n",
    "            return sum(nums)\n",
    "        \n",
    "        nums = sorted(nums)\n",
    "        tmp = nums[0] + nums[1] + nums[-1]\n",
    "        for i in range(len(nums)-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue                \n",
    "            j = i + 1\n",
    "            k = len(nums)-1 \n",
    "            while j < k:\n",
    "                res = nums[i] + nums[j] + nums[k]\n",
    "                \n",
    "                if abs(res-target) < abs(tmp - target):\n",
    "                    tmp = res\n",
    "                elif res < target:\n",
    "                    j += 1\n",
    "                elif res == target:\n",
    "                     return res\n",
    "                else:\n",
    "                    k -= 1\n",
    "        return tmp\n",
    "                \n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        \n",
    "        nums.sort()\n",
    "        init_num = float('inf')\n",
    "        result = []\n",
    "        for i in range(len(nums)):\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            while left < right:\n",
    "                tmp_sum = nums[i] + nums[left] + nums[right]\n",
    "                abs_num = abs(target - tmp_sum)\n",
    "                \n",
    "                if abs_num <= init_num:\n",
    "                    init_num = abs_num\n",
    "                    result.append(tmp_sum)\n",
    "                    \n",
    "                if tmp_sum < target:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "            \n",
    "        return result[-1]\n",
    "                \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "        res=0\n",
    "        min_distance=9999\n",
    "        \n",
    "        nums.sort()\n",
    "        print(nums)\n",
    "        for i in range(len(nums)-2):\n",
    "            print('i:',i)\n",
    "            l=i+1\n",
    "            r=len(nums)-1\n",
    "            while(l<r):\n",
    "                sum = nums[i]+nums[l]+nums[r]\n",
    "                \n",
    "                if abs(target-sum)<min_distance:\n",
    "                    res=sum\n",
    "                    min_distance=abs(target-sum)\n",
    "                    print(i,l,r,sum)\n",
    "                    \n",
    "                if target==sum:\n",
    "                    return target\n",
    "                elif target>sum:\n",
    "                    l+=1\n",
    "                else:\n",
    "                    r-=1\n",
    "                    \n",
    "\n",
    "        return res\n",
    "                        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: 'List[int]', target: 'int') -> 'int':\n",
    "        nums.sort()\n",
    "        len_nums = len(nums)\n",
    "        \n",
    "        #这儿的res=None,而不是res等于一个数值\n",
    "        res = None\n",
    "        for i in range(len_nums-2): \n",
    "            j = i+1\n",
    "            k = len_nums-1\n",
    "            min = nums[0] + nums[1] + nums[2]\n",
    "            print(min)\n",
    "            max = nums[i] + nums[k] + nums[k-1]\n",
    "            if min > target:\n",
    "                res = min\n",
    "                break\n",
    "            elif max < target:\n",
    "            #     # if res == None:\n",
    "            #     #     res = max\n",
    "            #     # if abs(max-target) < abs(res-target):\n",
    "            #     #     res = max\n",
    "            #     #     print(max)\n",
    "                 res = max if res == None or abs(max-target) < abs(res-target) else res\n",
    "\n",
    "            else:\n",
    "                while j<k: \n",
    "                    s = nums[i]+nums[j]+nums[k]\n",
    "                    if res == None:\n",
    "                        res = s\n",
    "                    if abs(s-target) < abs(res-target):\n",
    "                        res = s\n",
    "                    if s == target:\n",
    "                        return s\n",
    "                    elif s > target:\n",
    "                        k -= 1\n",
    "                    else:\n",
    "                        j += 1\n",
    "        return res\n",
    "                \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: 'List[int]', target: 'int') -> 'int':\n",
    "        nums.sort()\n",
    "        len_nums = len(nums)\n",
    "        best_dist = float('inf')\n",
    "        best_sum = 0\n",
    "        res = []\n",
    "        for key, value in enumerate(nums[:len_nums-2]):\n",
    "            l, r = key+1,len_nums-1\n",
    "            if nums[l] + nums[l+1] + value > target:\n",
    "                res.append(nums[l] + nums[l+1] + value)\n",
    "            elif nums[r] + nums[r-1] + nums[r-2] < target:\n",
    "                res.append(nums[l] + nums[l+1] + value)\n",
    "            while l < r:\n",
    "                tmp = value + nums[l] + nums[r]\n",
    "                res.append(tmp)\n",
    "                if tmp == target:\n",
    "                    return target\n",
    "                \n",
    "                # if abs(tmp-target) < best_dist:\n",
    "                #     best_dist = abs(tmp-target)\n",
    "                #     best_sum = tmp\n",
    "                if tmp < target:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        # res.append(best_sum)\n",
    "        res.sort(key = lambda x: abs(x - target))\n",
    "        return res[0]\n",
    "                    \n",
    "            \n",
    "                \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: int\n",
    "        \"\"\"\n",
    "\n",
    "        l = len(nums)\n",
    "        nums.sort()\n",
    "        x = []\n",
    "        for i in range(1, l-1):\n",
    "            start = 0\n",
    "            end = l-1\n",
    "            change = target - nums[i]\n",
    "            while start < i and end > i:\n",
    "                x.append(nums[start] + nums[end] - change)\n",
    "                if nums[start] + nums[end] > change:\n",
    "                    end -= 1\n",
    "                elif nums[start] + nums[end] < change:\n",
    "                    start += 1\n",
    "                else:\n",
    "                    return target\n",
    "        change_list = [abs(j) for j in x]\n",
    "        min_num = min(change_list)\n",
    "        return x[change_list.index(min_num)] + target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        if not nums or len(nums)<3:\n",
    "            return None\n",
    "        length = len(nums)\n",
    "        nums.sort()\n",
    "        ans =nums[0] + nums[1] + nums[2] \n",
    "\n",
    "        for i in range(length-2):\n",
    "            first = i + 1\n",
    "            last = length - 1\n",
    "            while first <last:\n",
    "                temp=nums[i]+nums[first]+nums[last]\n",
    "                if abs(temp - target) < abs(ans - target):\n",
    "                        ans = temp\n",
    "                if temp == target:\n",
    "                    return target\n",
    "                elif temp < target:\n",
    "                    first += 1\n",
    "                else:\n",
    "                    last -= 1\n",
    "                \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        res = nums[0] + nums[1] + nums[2]\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        for i in range(n - 2):\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            while j < k:\n",
    "                num_sum = nums[i] + nums[j] + nums[k]\n",
    "                if num_sum == target:\n",
    "                    return target\n",
    "                elif num_sum > target:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    j += 1\n",
    "                if abs(num_sum - target) < abs(res - target):\n",
    "                    res = num_sum\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        res = float('inf')\n",
    "        for i in range(n):\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            while left < right:  \n",
    "                cur = nums[i] + nums[left] + nums[right]\n",
    "                if cur == target:\n",
    "                    return target\n",
    "                if abs(cur - target) < abs(res - target):\n",
    "                    res = cur\n",
    "                if cur < target:\n",
    "                        left += 1\n",
    "                elif cur > target:\n",
    "                        right -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        closest_sum = float('inf')\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)-2):\n",
    "            start = i+1\n",
    "            end = len(nums)-1\n",
    "            while(start < end):\n",
    "                temp = nums[i] + nums[start] + nums[end]\n",
    "                if(temp == target):\n",
    "                    return temp\n",
    "                elif(temp > target):\n",
    "                    end -= 1\n",
    "                else:\n",
    "                    start += 1\n",
    "                if(abs(closest_sum-target) > abs(temp-target)):\n",
    "                    closest_sum = temp\n",
    "        return closest_sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        ans = sum(nums[0:3])\n",
    "        if ans > target:\n",
    "            return ans\n",
    "        if sum(nums[-3:]) < target:\n",
    "            return sum(nums[-3:])\n",
    "        for i in range(len(nums)-2):\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            while right > left:\n",
    "                _sum = nums[i] + nums[left] + nums[right]\n",
    "                if abs(_sum - target) < abs(ans-target):\n",
    "                    ans = _sum\n",
    "                if _sum > target:\n",
    "                    right -= 1\n",
    "                elif _sum < target:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    return _sum\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        result = nums[0]+nums[1]+nums[2]\n",
    "        length = len(nums)\n",
    "        for i in range(length-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            left,right = i+1,length-1\n",
    "            while right > left:\n",
    "                temp = nums[i]+nums[left]+nums[right]\n",
    "                if abs(temp-target)<abs(result-target):\n",
    "                    result = temp\n",
    "                if temp - target>0:\n",
    "                    right = right - 1\n",
    "                    if nums[right] == nums[right+1]:\n",
    "                        continue\n",
    "                else:\n",
    "                    left = left + 1\n",
    "                    if nums[left] == nums[left-1]:\n",
    "                        continue\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "            nums.sort()\n",
    "            n = len(nums)\n",
    "            best = 10**7\n",
    "            def update(cur):\n",
    "                nonlocal best\n",
    "                if abs(cur - target) < abs(best - target):\n",
    "                    best = cur\n",
    "\n",
    "            for first in range(n):\n",
    "                if first > 0 and nums[first] == nums[first - 1]:\n",
    "                    continue\n",
    "                j, k = first + 1, n - 1\n",
    "                while j < k:\n",
    "                    s = nums[first] + nums[j] + nums[k]\n",
    "                    if s == target:\n",
    "                        return target\n",
    "                    update(s)\n",
    "\n",
    "                    if s > target:\n",
    "                        k0 = k - 1\n",
    "                        while j < k0 and nums[k] == nums[k0]:\n",
    "                            k0 -= 1\n",
    "                        k = k0\n",
    "                    else:\n",
    "                        j0 = j + 1\n",
    "                        while j0 < k and nums[j] == nums[j0]:\n",
    "                            j0 += 1\n",
    "                        j = j0\n",
    "            return best"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        if not nums or len(nums)<=2:\n",
    "            return\n",
    "        # if len(nums)==3:\n",
    "        #     return sum(nums)\n",
    "\n",
    "        nums.sort()\n",
    "        minsum = 1000000\n",
    "        res = 0\n",
    "        # res = []\n",
    "        for i in range(len(nums)-2):\n",
    "            m = i+1\n",
    "            n = len(nums)-1\n",
    "            while m<n:\n",
    "                tempsum = nums[i]+nums[m]+nums[n]\n",
    "                # print(nums[i],nums[m],nums[n])\n",
    "                # if tempsum==target:\n",
    "                #     return tempsum\n",
    "                if tempsum<target:\n",
    "                    m+=1\n",
    "                elif tempsum>target:\n",
    "                    n-=1\n",
    "                else:\n",
    "                    return tempsum\n",
    "                if abs(tempsum-target)<abs(minsum-target):\n",
    "                    minsum = tempsum\n",
    "\n",
    "        return minsum\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\r\n",
    "        nums.sort()\r\n",
    "        min_res = 2**31\r\n",
    "        result = None\r\n",
    "        \r\n",
    "        for i in range(len(nums)):\r\n",
    "            l = i + 1\r\n",
    "            r = len(nums) - 1 \r\n",
    "            while l < r:\r\n",
    "                s = nums[i] + nums[l] + nums[r]\r\n",
    "                direction = target - s\r\n",
    "                res = abs(direction)\r\n",
    "\r\n",
    "                if res < min_res:\r\n",
    "                    min_res = res\r\n",
    "                    result = s\r\n",
    "               \r\n",
    "                if direction < 0:\r\n",
    "                    r -= 1\r\n",
    "                elif direction > 0:\r\n",
    "                    l += 1\r\n",
    "                else:\r\n",
    "                    return s\r\n",
    "\r\n",
    "                                \r\n",
    "                \r\n",
    "        return result\r\n",
    "\r\n",
    "            \r\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        print(nums)\n",
    "        ans = 10**7\n",
    "        def update(cur):\n",
    "            nonlocal ans\n",
    "            if abs(cur-target) < abs(ans-target) :\n",
    "                ans = cur\n",
    "            #print('s,ans',cur,ans)\n",
    "        for pa in range(n-2):\n",
    "            pb = pa + 1\n",
    "            pc = n - 1\n",
    "            while pb < pc :\n",
    "                print(pa,pb,pc)\n",
    "                s = nums[pa] + nums[pb] + nums[pc]\n",
    "                if s == target :\n",
    "                    return target\n",
    "                update(s)\n",
    "                if s > target: \n",
    "                    pc = pc - 1\n",
    "                    while pb < pc and nums[pc] == nums[pc+1] :\n",
    "                        pc -= 1\n",
    "                else : \n",
    "                    pb = pb + 1\n",
    "                    while pb < pc and nums[pb] == nums[pb-1] :\n",
    "                        pb += 1 \n",
    "        return ans\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        ###三个数的和，与target相减，取最小的那个\n",
    "        #三重循环，时间复杂度太高\n",
    "        ##怎么做呢？\n",
    "        ##数组排序，固定一个数？加双指针移动？\n",
    "        n=len(nums)\n",
    "        \n",
    "        nums.sort()\n",
    "        res=[]\n",
    "        if n<3:return 0\n",
    "\n",
    "        for i in range(len(nums)-2):\n",
    "            l=i+1\n",
    "            r=n-1\n",
    "            value=nums[i]+nums[l]+nums[r]-target\n",
    "         \n",
    "            res.append(value)\n",
    "            while l<r:\n",
    "                if value==0:\n",
    "                    return nums[i]+nums[l]+nums[r]\n",
    "                while (value>0 and l<r):\n",
    "                    r=r-1\n",
    "                    if l<r:\n",
    "                        value=nums[i]+nums[l]+nums[r]-target\n",
    "                        res.append(value)\n",
    "                while (value<0 and l<r):\n",
    "                    l=l+1\n",
    "                    if l<r:\n",
    "                        value=nums[i]+nums[l]+nums[r]-target\n",
    "                        res.append(value)\n",
    "\n",
    "        abs_res=[abs(i) for i in res]\n",
    "        min_value=min(abs_res)\n",
    "        result=res[abs_res.index(min_value)]+target\n",
    "        \n",
    "        return result\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums)<=3:\n",
    "            return sum(nums)\n",
    "        nums.sort()\n",
    "        if sum(nums[-3:])<=target:\n",
    "            return sum(nums[-3:])\n",
    "        last_error=nums[0]+nums[1]+nums[2]-target\n",
    "        if last_error>=0:\n",
    "            return nums[0]+nums[1]+nums[2]\n",
    "        length=len(nums)\n",
    "        result=[last_error]\n",
    "        flag=False\n",
    "        for i in range(length-2):\n",
    "            for j in range(i+1,length-1):\n",
    "                for k in range(j+1,length):\n",
    "                    current=nums[i]+nums[j]+nums[k]\n",
    "                    error=current-target\n",
    "                    if error==0:\n",
    "                        return current\n",
    "                    elif error>0:\n",
    "                        if k>j+1:\n",
    "                            if abs(last_error)>error:\n",
    "                                result.append(error)\n",
    "                            else:\n",
    "                                result.append(last_error)\n",
    "                        else:\n",
    "                            result.append(error)\n",
    "                        break\n",
    "                    last_error=error\n",
    "                result.append(error) #if all is less than 0\n",
    "\n",
    "        min_error=result[0]\n",
    "        for index in range(1,len(result)):\n",
    "            error=result[index]\n",
    "            if abs(error)<abs(min_error):\n",
    "                min_error=error\n",
    "    \n",
    "        return target+min_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:       \n",
    "        nums=sorted(nums)\n",
    "        res=sum(nums[:3])\n",
    "        for i in range(len(nums)-2):\n",
    "            left = i+1\n",
    "            right=len(nums)-1\n",
    "            while left<right:\n",
    "                if nums[i]+nums[left]+nums[right]-target==0:\n",
    "                    return nums[i]+nums[left]+nums[right]\n",
    "                if abs(nums[i]+nums[left]+nums[right]-target)<abs(res-target):\n",
    "                    res=(nums[i]+nums[left]+nums[right])\n",
    "                    continue\n",
    "                if nums[i]+nums[left]+nums[right]-target>0:\n",
    "                    right-=1\n",
    "                    continue\n",
    "                if nums[i]+nums[left]+nums[right]-target<0:\n",
    "                    left+=1\n",
    "        return res\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        dis = 10 ** 5\n",
    "        nums.sort()\n",
    "        res = 0\n",
    "\n",
    "        n = len(nums)\n",
    "        for i in range(n-2):\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            \n",
    "            while left < right:\n",
    "                s = nums[left] + nums[right] + nums[i]\n",
    "                if abs(s - target) < dis:\n",
    "                    res = s\n",
    "                    dis = abs(s - target)\n",
    "\n",
    "                if s > target:\n",
    "                    right -= 1\n",
    "                elif s < target:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    return target\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        res = nums[0] + nums[1]+ nums[2]\n",
    "        for i in range(len(nums)):\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1\n",
    "            while l < r:\n",
    "                sums = nums[i]+ nums[l]+ nums[r]\n",
    "                if abs(target - sums) < abs(target - res):\n",
    "                    res = sums\n",
    "\n",
    "                if target > sums:\n",
    "                    l += 1\n",
    "                    \n",
    "                elif target < sums:\n",
    "                    r -= 1\n",
    "\n",
    "                else:\n",
    "                    return res\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums, target):\n",
    "        ret = float('inf')\n",
    "        nums.sort()\n",
    "        length = len(nums)\n",
    "        for i in range(length - 2):\n",
    "            left = i + 1\n",
    "            right = length - 1\n",
    "            while left < right:\n",
    "                tmp = nums[i] + nums[left] + nums[right]\n",
    "                ret = tmp if abs(tmp - target) < abs(ret - target) else ret\n",
    "                if tmp == target:\n",
    "                    return target\n",
    "                if tmp > target:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left += 1\n",
    "        return ret\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        nums_len = len(nums)\n",
    "        ans, total_num = 99999999, 99999999\n",
    "        for i in range(nums_len):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            left = i + 1\n",
    "            right = nums_len - 1\n",
    "            while left < right:\n",
    "                total = nums[i] + nums[left] + nums[right]\n",
    "                diff = self.calculate_difference(target, total)\n",
    "                if diff == 0:\n",
    "                    return total\n",
    "                if ans > diff:\n",
    "                    ans = diff\n",
    "                    total_num = total\n",
    "                if total > target:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left += 1\n",
    "\n",
    "        return total_num\n",
    "                \n",
    "    \n",
    "    def calculate_difference(self, num1: int, num2: int):\n",
    "        if num1 >= num2:\n",
    "            return num1 -num2\n",
    "        return num2 - num1\n",
    "\n",
    "\n",
    "# -10 -7 -2 0 4 8 12"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        re_min = 0 #存储当前最小的差值\n",
    "        \n",
    "        for i in range(n):\n",
    "            low = i+1\n",
    "            high = n-1\n",
    "            while low < high:\n",
    "                three_sum = nums[i] + nums[low] + nums[high]\n",
    "                x = target - three_sum #当前三数的差值\n",
    "                if re_min == 0:\n",
    "                    re_min = abs(x)\n",
    "                    sum_min = three_sum #sum_min为当前最接近的和\n",
    "                \n",
    "                if abs(x) < re_min:\n",
    "                    re_min = abs(x)\n",
    "                    sum_min = three_sum\n",
    "                \n",
    "                if three_sum == target:\n",
    "                    return target\n",
    "                elif three_sum < target:\n",
    "                    low += 1\n",
    "                else:\n",
    "                    high -= 1\n",
    "        \n",
    "        return sum_min"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        best = float(\"inf\")\n",
    "\n",
    "        def update(cur):\n",
    "            nonlocal best\n",
    "            if abs(cur-target) < abs(best-target):\n",
    "                best = cur\n",
    "        \n",
    "        for i in range(n):\n",
    "            if i>0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            j, k = i+1, n-1\n",
    "            while j<k:\n",
    "                total = nums[i] + nums[j] + nums[k]\n",
    "                if total == target:\n",
    "                    return target\n",
    "                update(total)\n",
    "                if total>target:\n",
    "                    k = k-1\n",
    "                    while j<k and nums[k] == nums[k+1]:\n",
    "                        k -= 1\n",
    "                else:\n",
    "                    j = j+1\n",
    "                    while j<k and nums[j] == nums[j-1]:\n",
    "                        j += 1\n",
    "        return best"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ans = inf\n",
    "        for i, v in enumerate(nums):\n",
    "            j, k = i + 1, n - 1\n",
    "            while j < k:\n",
    "                t = v + nums[j] + nums[k]\n",
    "                if t == target:\n",
    "                    return t\n",
    "                if abs(t - target) < abs(ans - target):\n",
    "                    ans = t\n",
    "                if t > target:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    j += 1\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumClosest(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        nlen = len(nums)\n",
    "        minb = float('inf')\n",
    "        for i in range(nlen):\n",
    "            a = nums[i]\n",
    "            pb = i + 1\n",
    "            pc = nlen - 1\n",
    "            while pb < pc:\n",
    "                tmp = a + nums[pb] + nums[pc]\n",
    "                if tmp > target:\n",
    "                    pc -= 1\n",
    "                elif tmp < target:\n",
    "                    pb += 1\n",
    "                else:\n",
    "                    return tmp\n",
    "                bias = tmp - target\n",
    "                if abs(bias) < minb:\n",
    "                    minb = abs(bias)\n",
    "                    ans = bias + target\n",
    "\n",
    "        return ans\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        if n < 3:return 0\n",
    "        res = 0\n",
    "        nums.sort()\n",
    "        for i in range(n-2):\n",
    "            if 3*nums[i] >= target:break\n",
    "            for j in range(i+1,n-1):\n",
    "                if nums[i] + 2*nums[j] >= target:break\n",
    "                cnt = bisect.bisect_left(nums[j+1:], target-nums[i]-nums[j]) # 返回小于查找数的数目个数\n",
    "                res += cnt\n",
    "                if cnt <= 0:break\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums) < 3:\n",
    "            return 0\n",
    "        res = 0\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)-2):\n",
    "            left, right = i+1, len(nums)-1\n",
    "            while left < right:\n",
    "                if nums[i] + nums[left] + nums[right] < target:\n",
    "                    res += (right-left)\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        nums.sort()\n",
    "\n",
    "        res, n = 0, len(nums)\n",
    "        for i in range(n-2): # 第一个数位置，0~n-3表示还得留2个数给第2个和第3个（n-2、n-1）\n",
    "            res_sub = 0 # 第一个数是nums[i]的前提下，三数的组合个数\n",
    "            left = i + 1 # 第二个数位置\n",
    "            right = n - 1 # 第三个数位置\n",
    "            while left < right:\n",
    "                if nums[i] + nums[left] + nums[right] < target:\n",
    "                    res_sub += right - left # left确定的条件下，有right-left对儿组合，使之对儿数字和小于target\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1 # 三数和大于等于target，需要right左移，减少三数和\n",
    "            res += res_sub\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums) < 3:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        l = len(nums)\n",
    "        ans = 0\n",
    "        for i in range(l):\n",
    "            left = target - nums[i]\n",
    "            for j in range(i+1,l):\n",
    "                right = left - nums[j]\n",
    "                for k in range(j+1, l):\n",
    "                    if nums[k] < right:\n",
    "                        ans += 1\n",
    "                    else:\n",
    "                        break\n",
    "        return ans\n",
    "\n",
    "\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        result = 0\n",
    "        n = len(nums)\n",
    "        for i in range(n-2):\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                curr = nums[i] + nums[left] + nums[right]\n",
    "                if curr >= target:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    result += right - left\n",
    "                    left += 1 \n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        \n",
    "        def double_pointers(left, right=n-1):\n",
    "            count = 0\n",
    "            start = left - 1\n",
    "            while left < right:\n",
    "                if nums[start] + nums[left] + nums[right] < target:\n",
    "                    count += right - left\n",
    "                    left += 1  \n",
    "                else:\n",
    "                    right -= 1\n",
    "\n",
    "\n",
    "            # print(count)\n",
    "            return count\n",
    "        \n",
    "        \n",
    "        # 特殊案例\n",
    "        if n == 0:\n",
    "            return 0\n",
    "        if n == 1:\n",
    "            if nums[0] < target:\n",
    "                return 1\n",
    "            else:\n",
    "                return 0\n",
    "        \n",
    "        nums.sort()\n",
    "        i = 0\n",
    "        count = 0\n",
    "        while i < n-2:\n",
    "            # print(i)\n",
    "            # if i > 0 and nums[i-1] == nums[i]:  # 由于返回的是下标的三元组，因此无需去重\n",
    "            #     i += 1\n",
    "            #     continue\n",
    "            count += double_pointers(i+1)\n",
    "            i += 1 \n",
    "        \n",
    "        return count \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        # if len(nums) < 3:\n",
    "        #     return 0\n",
    "        # nums.sort()\n",
    "        # l = len(nums)\n",
    "        # ans = 0\n",
    "        # for i in range(l):\n",
    "        #     left = target - nums[i]\n",
    "        #     for j in range(i+1,l):\n",
    "        #         right = left - nums[j]\n",
    "        #         for k in range(j+1, l):\n",
    "        #             if nums[k] < right:\n",
    "        #                 ans += 1\n",
    "        #             else:\n",
    "        #                 break\n",
    "        # return ans\n",
    "        ans = 0\n",
    "        cnt = Counter(nums)\n",
    "        lst = list(cnt.keys())\n",
    "\n",
    "        # x+y+z\n",
    "        for x, y, z in combinations(lst, 3):\n",
    "            if x != y and y != z and x != y and x + y + z < target:\n",
    "                ans += cnt[x] * cnt[y] * cnt[z]\n",
    "\n",
    "        # x+x+x\n",
    "        for x in lst:\n",
    "            if x * 3 < target:\n",
    "                ans += cnt[x] * (cnt[x] - 1) * (cnt[x] - 2) // 6\n",
    "        \n",
    "        for x, y in combinations(lst, 2):\n",
    "            # x+x+y\n",
    "            if x * 2 + y < target:\n",
    "                ans += cnt[y] * cnt[x] * (cnt[x] - 1) // 2\n",
    "            # x+y+y\n",
    "            if x + y * 2 < target:\n",
    "                ans += cnt[x] * cnt[y] * (cnt[y] - 1) // 2\n",
    "        return ans\n",
    "\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        num = 0\n",
    "        start_index= 0\n",
    "        for start_index in range(len(nums)-2):\n",
    "            left_index = start_index +1\n",
    "            right_index= len(nums)-1\n",
    "            while left_index < right_index:\n",
    "                if nums[start_index] + nums[left_index] + nums[right_index] >= target:\n",
    "                    right_index -=1\n",
    "                else:\n",
    "                    num += (right_index-left_index)\n",
    "                    left_index += 1\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums)<3:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        ans = 0\n",
    "        for i in range(len(nums)-2):\n",
    "            left = i + 1\n",
    "            right = len(nums) -1 \n",
    "            while left < right:\n",
    "                if nums[left] + nums[right] < target - nums[i]:\n",
    "                    ans += right - left\n",
    "                    left +=1\n",
    "                else:\n",
    "                    right -=1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        res = 0\n",
    "        for a in range(len(nums)-2):\n",
    "            b, c = a + 1, len(nums) - 1\n",
    "            while b < c:\n",
    "                if nums[b] + nums[c] < target - nums[a]:\n",
    "                    res += c - b \n",
    "                    b += 1\n",
    "                elif nums[b] + nums[c] >= target - nums[a]:\n",
    "                    c -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        res = 0\n",
    "        for i in range(n-2):\n",
    "            x = nums[i]\n",
    "            right = n-1\n",
    "            for j in range(i+1,n-1):\n",
    "                y = nums[j]\n",
    "                if x+y+nums[j+1]>=target:\n",
    "                    break\n",
    "                left= j+1\n",
    "                while left<=right:\n",
    "                    mid = (right-left)//2+left\n",
    "                    if nums[mid]+x+y<target:\n",
    "                        left = mid+1\n",
    "                    else:\n",
    "                        right = mid-1\n",
    "                res+=right-j\n",
    "                right = min(n-1,right+1)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort() \n",
    "        n = len(nums) \n",
    "\n",
    "        ans = 0 \n",
    "\n",
    "        def lower_bound(nums, k, l, r):\n",
    "            while (l < r):\n",
    "                mid = (l + r) >> 1 \n",
    "                if nums[mid] >= k:\n",
    "                    r = mid \n",
    "                else:\n",
    "                    l = mid + 1 \n",
    "            return l \n",
    "\n",
    "\n",
    "        for i in range(n-2):\n",
    "            for j in range(i+1, n-1):\n",
    "                k = target - nums[i] - nums[j] \n",
    "                idx = lower_bound(nums, k, j+1, n-1) \n",
    "                if nums[idx] < k:\n",
    "                    ans += idx - j \n",
    "                else:\n",
    "                    ans += idx - j - 1 \n",
    "        \n",
    "        return ans \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        res, n = 0, len(nums)\n",
    "        for i in range(n):\n",
    "            l, r = i + 1, n - 1\n",
    "            while l < r:\n",
    "                three = nums[i] + nums[l] + nums[r]\n",
    "                if three >= target:\n",
    "                    r -= 1\n",
    "                else: # [-1, -1, -1, 0, 1, 1, 1], 2\n",
    "                    res += r - l\n",
    "                    l += 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n=len(nums)\n",
    "        nums.sort()\n",
    "        r=n-1\n",
    "        ans=0\n",
    "        print(nums)\n",
    "        for i in range(n):\n",
    "            l=i+1\n",
    "            r=n-1\n",
    "            while l<r:\n",
    "                if nums[i]+nums[l]+nums[r]>=target:\n",
    "                    r=r-1\n",
    "                else:\n",
    "                    ans+=r-l\n",
    "                    l=l+1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        if not nums  or len(nums)<3:\n",
    "            return 0\n",
    "\n",
    "        nums.sort()\n",
    "        if sum(nums[-3:])<target:\n",
    "            return len(nums)-2\n",
    "        if sum(nums[:3])>=target:\n",
    "            return 0\n",
    "        res = 0\n",
    "        for i in range(len(nums)-2):\n",
    "            l = i+1\n",
    "            r = len(nums) -1 \n",
    "            while l < r:\n",
    "                if nums[i] + nums[l] + nums[r] < target:\n",
    "                    res = res + r - l\n",
    "                    l+=1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return res \n",
    "\n",
    "\n",
    "                \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        if not nums and len(nums) < 3:\n",
    "            return 0\n",
    "\n",
    "        nums.sort()\n",
    "        count = 0\n",
    "        for i in range(len(nums)-2):\n",
    "            for j in range(i+1, len(nums)-1):\n",
    "                if nums[j+1] >= target-nums[i]-nums[j]:\n",
    "                    continue\n",
    "                if nums[-1] < target-nums[i]-nums[j]:\n",
    "                    count = count + len(nums)-1 - j\n",
    "                    continue\n",
    "                k = self.binary_search(nums, j, target-nums[i]-nums[j])\n",
    "                count = count + k-j\n",
    "        return count\n",
    "\n",
    "    def binary_search(self, nums, start, target):\n",
    "        low = start\n",
    "        high =  len(nums)  - 1\n",
    "        while low < high:\n",
    "            mid = (high-low + 1) // 2 + low\n",
    "            if nums[mid] < target:\n",
    "                low = mid\n",
    "            else:\n",
    "                high = mid - 1\n",
    "        return low \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "        for i in range(n-2):\n",
    "            j, k = i + 1, n - 1\n",
    "            while j < k:\n",
    "                cur = nums[i] + nums[j] + nums[k]\n",
    "                if cur >= target:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    ans += k - j\n",
    "                    j += 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums) < 3:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        l = len(nums)\n",
    "        ans = 0\n",
    "        for i in range(l):\n",
    "            left = target - nums[i]\n",
    "            for j in range(i+1,l):\n",
    "                right = left - nums[j]\n",
    "                for k in range(j+1, l):\n",
    "                    if nums[k] < right:\n",
    "                        ans += 1\n",
    "                    else:\n",
    "                        break\n",
    "        return ans\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        if n < 3:\n",
    "            return 0\n",
    "        res = 0\n",
    "        nums.sort()\n",
    "        for i in range(n-2):\n",
    "            res += self.twoSumSmaller(nums, i+1, target-nums[i])\n",
    "        return res\n",
    "\n",
    "    def twoSumSmaller(self, nums, start, target):\n",
    "        num_small = 0\n",
    "        n = len(nums)\n",
    "        left,right = start,n-1\n",
    "        while left < right:\n",
    "            sum_ = nums[left] + nums[right]\n",
    "            if sum_ < target:\n",
    "                num_small += right-left\n",
    "                left += 1\n",
    "            else:\n",
    "                right -= 1\n",
    "        return num_small"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        length = len(nums)\n",
    "        sorted_nums = sorted(nums)\n",
    "        res = 0\n",
    "\n",
    "        for start in range(length-2):\n",
    "            remained_target = target - sorted_nums[start]\n",
    "\n",
    "            i = start + 1\n",
    "            j = length - 1\n",
    "\n",
    "            while i < j:\n",
    "                if sorted_nums[j] + sorted_nums[i] >= remained_target:\n",
    "                    j -= 1\n",
    "                else:\n",
    "                    res += (j - i)\n",
    "                    i += 1\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums) \n",
    "        nums.sort() \n",
    "        ans = 0 \n",
    "        for i in range(2, n):\n",
    "            j = i-1\n",
    "            k = 0 \n",
    "            while k < j:\n",
    "                while k < j and nums[j] + nums[k] >= target - nums[i]:\n",
    "                    j-=1 \n",
    "                ans += j - k \n",
    "                k += 1\n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        res, n = 0, len(nums)\n",
    "        for i in range(n):\n",
    "            if nums[i] >= 1 / 3 * target:\n",
    "                continue\n",
    "            l, r = i + 1, n - 1\n",
    "            while l < r:\n",
    "                three = nums[i] + nums[l] + nums[r]\n",
    "                if three >= target:\n",
    "                    r -= 1\n",
    "                elif three < target:\n",
    "                    res += r - l\n",
    "                    l += 1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        if not nums or n < 3:\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        i = 0\n",
    "        ans = 0\n",
    "        while i <= n - 3:\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            while j < k:\n",
    "                if nums[i] + nums[j] + nums[k] < target:\n",
    "                    ans += (k - j)\n",
    "                    j = j + 1\n",
    "                    k = n - 1\n",
    "                else:\n",
    "                    k = k - 1\n",
    "            i += 1\n",
    "        return ans\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "\n",
    "\n",
    "\n",
    "        for i in range(n):\n",
    "            l,r = i+1,n-1\n",
    "            need = target - nums[i]\n",
    "            while l < r:\n",
    "                sumNum = nums[r] + nums[l]\n",
    "                if sumNum >= need:\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    ans +=  r - l\n",
    "                    l += 1\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        size = len(nums)\n",
    "        res = 0\n",
    "        for i in range(size):\n",
    "            left, right = i + 1, size - 1\n",
    "            while left < right:\n",
    "                total = nums[i] + nums[left] + nums[right]\n",
    "                if total < target:\n",
    "                    res += (right - left)\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        if not nums and len(nums) < 3:\n",
    "            return 0\n",
    "\n",
    "        nums.sort()\n",
    "        count = 0\n",
    "        for i in range(len(nums)-2):\n",
    "            for j in range(i+1, len(nums)-1):\n",
    "                if nums[j+1] >= target-nums[i]-nums[j]:\n",
    "                    continue\n",
    "                k = self.binary_search(nums, j, target-nums[i]-nums[j])\n",
    "                count = count + k-j\n",
    "        return count\n",
    "\n",
    "    def binary_search(self, nums, start, target):\n",
    "        low = start\n",
    "        high =  len(nums)  - 1\n",
    "        while low < high:\n",
    "            mid = (high-low + 1) // 2 + low\n",
    "            if nums[mid] < target:\n",
    "                low = mid\n",
    "            else:\n",
    "                high = mid - 1\n",
    "        return low \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        #使nums[i] + nums[j] + nums[k] < target\n",
    "        n=len(nums)\n",
    "        ans=0\n",
    "        for i in range(n):\n",
    "            left,right=i+1,n-1\n",
    "            while left < right:\n",
    "                res = nums[i] + nums[left] +nums[right]\n",
    "                if res < target:\n",
    "                    ans+=right-left\n",
    "                    left+=1\n",
    "                else:\n",
    "                    right-=1\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        if n < 3:\n",
    "            return 0\n",
    "        \n",
    "        count = 0\n",
    "        for i in range(n - 2):\n",
    "            left, right = i + 1, n - 1\n",
    "            while left < right:\n",
    "                temp_sum = nums[i] + nums[left] + nums[right]\n",
    "                if temp_sum < target:\n",
    "                    count += (right - left)\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return count\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "\n",
    "        if not nums  or len(nums)<3:\n",
    "            return 0\n",
    "\n",
    "        nums.sort()\n",
    "        if sum(nums[-3:])<target:\n",
    "            return len(nums)-2\n",
    "        if sum(nums[:3])>=target:\n",
    "            return 0\n",
    "        res = 0\n",
    "        for i in range(len(nums)-2):\n",
    "            l = i+1\n",
    "            r = len(nums) -1 \n",
    "            while l < r:\n",
    "                if nums[i] + nums[l] + nums[r] < target:\n",
    "                    res = res + r - l\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return res \n",
    "\n",
    "\n",
    "                \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        def double_pointers(left, right):\n",
    "            count = 0\n",
    "            start = left - 1\n",
    "            while left < right:\n",
    "                cur_sum = nums[start] + nums[left] + nums[right]\n",
    "                if cur_sum < target:\n",
    "                    count += right - left\n",
    "                    left += 1  \n",
    "                else:\n",
    "                    right -= 1\n",
    "\n",
    "\n",
    "            # print(count)\n",
    "            return count\n",
    "        \n",
    "        n = len(nums)\n",
    "        # 特殊案例\n",
    "        if n == 0:\n",
    "            return 0\n",
    "        if n == 1:\n",
    "            if nums[0] < target:\n",
    "                return 1\n",
    "            else:\n",
    "                return 0\n",
    "        \n",
    "        nums.sort()\n",
    "        i = 0\n",
    "        count = 0\n",
    "        while i < n-2:\n",
    "            # print(i)\n",
    "            # if i > 0 and nums[i-1] == nums[i]:  # 由于返回的是下标的三元组，因此无需去重\n",
    "            #     i += 1\n",
    "            #     continue\n",
    "            count += double_pointers(i+1, n-1)\n",
    "            i += 1 \n",
    "        \n",
    "        return count \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums) < 3:\n",
    "            return 0\n",
    "\n",
    "        count = 0\n",
    "        nums.sort()\n",
    "        \n",
    "        for i in range(len(nums) - 2):\n",
    "            left, right = i + 1, len(nums) - 1\n",
    "            while left < right:\n",
    "                if nums[i] + nums[left] + nums[right] < target:\n",
    "                    count += right - left\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "\n",
    "        return count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        if len(nums) < 3:  # 处理边界条件\n",
    "            return 0\n",
    "        nums.sort()\n",
    "        ans = 0\n",
    "        for i in range(len(nums) - 2):  # 注意i,j,k三个指针不能重合\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            while left < right:\n",
    "                # 如果left和right之和小于target-nums[i]，left右移\n",
    "                if nums[left] + nums[right] < target - nums[i]:\n",
    "                    ans += right - left #### 统计的是原组的个数\n",
    "                    left += 1 \n",
    "                # 如果left和right之和大于target-nums[i]，right左移\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums=sorted(nums)\n",
    "        ret=0\n",
    "        def get_num(i,target):\n",
    "            temp=0\n",
    "            left=i+1\n",
    "            right=len(nums)-1\n",
    "            while left<right:\n",
    "                if nums[left]+nums[right]<target:\n",
    "                    temp+=right-left\n",
    "                    left+=1\n",
    "                else:\n",
    "                    right-=1\n",
    "            return temp\n",
    "        for i in range(len(nums)-2):\n",
    "            ret+=get_num(i,target-nums[i])\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        res = 0;\n",
    "        for i in range(n-2):\n",
    "            x = nums[i]\n",
    "            left,right=i+1,n-1\n",
    "            while left<right:\n",
    "                if x+nums[left]+nums[right]<target:\n",
    "                    res+=right-left\n",
    "                    left+=1\n",
    "                else:\n",
    "                    right-=1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        return sum(bisect.bisect_left(nums, target - nums[j] - nums[k], 0, j)\n",
    "            for k in range(len(nums)) for j in range(k)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from bisect import bisect_right\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums = sorted(nums)\n",
    "        psa = [float('-inf')] * (len(nums) + 1)\n",
    "        for i in range(len(nums)):\n",
    "            psa[i + 1] = max(psa[i] , nums[i]) #always increasing after sorted\n",
    "        res = 0\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i + 1 , len(nums)):\n",
    "                k = bisect_left(psa , target - nums[i] - nums[j]) - 2\n",
    "                if k - j > 0:\n",
    "                    res += k - j\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        ans = 0\n",
    "        cnt = Counter(nums)\n",
    "        lst = list(cnt.keys())\n",
    "\n",
    "        # x+y+z\n",
    "        for x, y, z in combinations(lst, 3):\n",
    "            if x != y and y != z and x != y and x + y + z < target:\n",
    "                ans += cnt[x] * cnt[y] * cnt[z]\n",
    "\n",
    "        # x+x+x\n",
    "        for x in lst:\n",
    "            if x * 3 < target:\n",
    "                ans += cnt[x] * (cnt[x] - 1) * (cnt[x] - 2) // 6\n",
    "        \n",
    "        for x, y in combinations(lst, 2):\n",
    "            # x+x+y\n",
    "            if x * 2 + y < target:\n",
    "                ans += cnt[y] * cnt[x] * (cnt[x] - 1) // 2\n",
    "            # x+y+y\n",
    "            if x + y * 2 < target:\n",
    "                ans += cnt[x] * cnt[y] * (cnt[y] - 1) // 2\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "        for i in range(n - 1, 1, -1):\n",
    "            new_tar = target - nums[i]\n",
    "            l, r = 0, i - 1\n",
    "            while r > 0:\n",
    "                l = min(l, r)\n",
    "                while l < r and nums[l] + nums[r] < new_tar:\n",
    "                    l += 1\n",
    "                ans += l \n",
    "                r -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from bisect import bisect_left\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n,res=len(nums),0\n",
    "        nums.sort()\n",
    "        for i,j in itertools.combinations(range(n),2):\n",
    "            res+=max(0,bisect_left(nums,target-nums[i]-nums[j])-j-1)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        cnt1 = Counter()\n",
    "        cnt2 = Counter()\n",
    "        res = 0\n",
    "        for i in nums:\n",
    "            for j in cnt2:\n",
    "                if i + j < target:\n",
    "                    res += cnt2[j]\n",
    "            for j in cnt1:\n",
    "                cnt2[i + j] += cnt1[j]\n",
    "            cnt1[i] += 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # def func(self, nums: List[int], L: int, target: int) -> int:    #两个数的和小于target\n",
    "    #     res = 0\n",
    "    #     R = len(nums) - 1\n",
    "    #     while L < R:\n",
    "    #         if nums[L] + nums[R] < target:\n",
    "    #             res += (R - L)\n",
    "    #             L += 1\n",
    "    #         else:\n",
    "    #             R -= 1\n",
    "    #     return res\n",
    "\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "    #     n = len(nums)\n",
    "    #     nums.sort()\n",
    "    #     res = 0\n",
    "    #     for i in range(n - 2):      #3个数的和，分解成2个数的和  先固定住一个变量，控制变量\n",
    "    #         res += self.func(nums, i + 1, target - nums[i])\n",
    "    #     return res\n",
    "\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        if n < 3:\n",
    "            return 0\n",
    "        res = 0\n",
    "        for i in range(len(nums)-2):\n",
    "            left = i+1\n",
    "            right = len(nums)-1\n",
    "            res_sm = target-nums[i]\n",
    "            while left < right:\n",
    "                if nums[right]+nums[left] < res_sm:\n",
    "                    res += (right-left)\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from bisect import *\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        len_n = len(nums)\n",
    "        cnt = 0\n",
    "        for i in range(len_n):\n",
    "            for j in range(i+1, len_n):\n",
    "                vi, vj = nums[i], nums[j]\n",
    "                vk = target - vi - vj\n",
    "                idx = bisect_left(nums, vk)\n",
    "                if idx-1 > j:\n",
    "                    cnt += idx-1 -j\n",
    "        \n",
    "        return cnt\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        answer = 0\n",
    "        n      = len(nums)\n",
    "        for i in range(n - 2):\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "\n",
    "            while j < k:\n",
    "                threeSum = nums[i] + nums[j] + nums[k]\n",
    "                if threeSum < target:\n",
    "                    answer += k - j\n",
    "                    j += 1\n",
    "                else:\n",
    "                    k -= 1\n",
    "        \n",
    "        return answer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def func(self, nums: List[int], L: int, target: int) -> int:    #两个数的和小于target\n",
    "        res = 0\n",
    "        R = len(nums) - 1\n",
    "        while L < R:\n",
    "            if nums[L] + nums[R] < target:\n",
    "                res += (R - L)\n",
    "                L += 1\n",
    "            else:\n",
    "                R -= 1\n",
    "        return res\n",
    "\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        res = 0\n",
    "        for i in range(n - 2):      #3个数的和，分解成2个数的和  先固定住一个变量，控制变量\n",
    "            res += self.func(nums, i + 1, target - nums[i])\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        n=len(nums)\n",
    "        nums.sort()\n",
    "        ans = 0\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                if target-nums[i]-nums[j] > nums[j]:\n",
    "                    cur = bisect_left(nums,target-nums[i]-nums[j])-1\n",
    "                    # print(i,j,cur,ans)\n",
    "                    ans += cur - j\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        res, n = 0, len(nums)\n",
    "        for i in range(n):\n",
    "            if nums[i] >= 1 / 3 * target:\n",
    "                continue\n",
    "            l, r = i + 1, n - 1\n",
    "            while l < r:\n",
    "                three = nums[i] + nums[l] + nums[r]\n",
    "                if three >= target:\n",
    "                    r -= 1\n",
    "                else: # [-1, -1, -1, 0, 1, 1, 1], 2\n",
    "                    res += r - l\n",
    "                    l += 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        ret=0\n",
    "        nums=sorted(nums)\n",
    "        i=0\n",
    "        while i<len(nums):\n",
    "            j=i+1\n",
    "            judge_=0\n",
    "            while j<len(nums):\n",
    "                k=j+1\n",
    "                judge=0\n",
    "                while k<len(nums):\n",
    "                    if nums[i]+nums[j]+nums[k]<target:\n",
    "                        ret+=1\n",
    "                        judge=1\n",
    "                        judge_=1\n",
    "                    else:\n",
    "                        break\n",
    "                    k+=1\n",
    "                if judge==0:\n",
    "                    break\n",
    "                j+=1\n",
    "            i+=1\n",
    "            if judge_==0:\n",
    "                break\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumSmaller(self, nums: List[int], target: int) -> int:\n",
    "        nums.sort()\n",
    "        def twoSumSmaller(seq, target):\n",
    "            res = 0\n",
    "            left = 0\n",
    "            right = len(seq)-1\n",
    "            while left != right:\n",
    "                if seq[left] + seq[right] < target:\n",
    "                    res += right - left\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "            return res\n",
    "        res = 0\n",
    "        for i in range(len(nums)-1):\n",
    "            seq = nums[i+1:]\n",
    "            res += twoSumSmaller(seq, target - nums[i])\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        mod, ans = 1000000007, 0\n",
    "        cnts = collections.Counter(arr)\n",
    "        vals = [k for k in cnts]\n",
    "        vals.sort()\n",
    "        n = len(vals)       \n",
    "        for i in range(n):\n",
    "            v1 = vals[i]\n",
    "            for j in range(i, n):\n",
    "                v2, v3 = vals[j], target - v1 - vals[j]\n",
    "                if v3 < v2: break\n",
    "                if v1 == v2 == v3:\n",
    "                    ans = (ans + cnts[v1] * (cnts[v1] - 1) * (cnts[v1] - 2) // 6) % mod\n",
    "                elif v1 == v2:\n",
    "                    ans = (ans + cnts[v1] * (cnts[v1] - 1) * cnts[v3] // 2) % mod\n",
    "                elif v2 == v3:\n",
    "                    ans = (ans + cnts[v1] * cnts[v2] * (cnts[v2] - 1) // 2) % mod\n",
    "                else:\n",
    "                    ans = (ans + cnts[v1] * cnts[v2] * cnts[v3]) % mod\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        ans = 0\n",
    "        A.sort()\n",
    "\n",
    "        for i, x in enumerate(A):\n",
    "            # We'll try to find the number of i < j < k\n",
    "            # with A[j] + A[k] == T, where T = target - A[i].\n",
    "\n",
    "            # The below is a \"two sum with multiplicity\".\n",
    "            T = target - A[i]\n",
    "            j, k = i+1, len(A) - 1\n",
    "\n",
    "            while j < k:\n",
    "                # These steps proceed as in a typical two-sum.\n",
    "                if A[j] + A[k] < T:\n",
    "                    j += 1\n",
    "                elif A[j] + A[k] > T:\n",
    "                    k -= 1\n",
    "                # These steps differ:\n",
    "                elif A[j] != A[k]: # We have A[j] + A[k] == T.\n",
    "                    # Let's count \"left\": the number of A[j] == A[j+1] == A[j+2] == ...\n",
    "                    # And similarly for \"right\".\n",
    "                    left = right = 1\n",
    "                    while j + 1 < k and A[j] == A[j+1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                    while k - 1 > j and A[k] == A[k-1]:\n",
    "                        right += 1\n",
    "                        k -= 1\n",
    "\n",
    "                    # We contributed left * right many pairs.\n",
    "                    ans += left * right\n",
    "                    ans %= MOD\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "                else:\n",
    "                    # M = k - j + 1\n",
    "                    # We contributed M * (M-1) / 2 pairs.\n",
    "                    ans += (k-j+1) * (k-j) // 2\n",
    "                    ans %= MOD\n",
    "                    break\n",
    "\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        n = len(arr)\n",
    "        ans = 0\n",
    "        MOD = int(1e9 + 7)\n",
    "        arr.sort()\n",
    "        for k in range(2, n):\n",
    "            l, r = 0, k - 1\n",
    "            while l < r:\n",
    "                if arr[l] + arr[r] + arr[k] == target:\n",
    "                    i, j = l, r\n",
    "                    if arr[l] == arr[r]:\n",
    "                        ans = (ans + (r - l) * (r - l + 1) // 2) % MOD\n",
    "                        break\n",
    "                    while arr[i] == arr[l]: i += 1\n",
    "                    while arr[j] == arr[r]: j -= 1\n",
    "                    ans = (ans + (i - l) * (r - j)) % MOD\n",
    "                    l, r = i, j\n",
    "                elif arr[l] + arr[r] + arr[k] < target:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        nums = Counter(arr)\n",
    "        res = 0\n",
    "        keys = sorted(nums.keys())\n",
    "        for i, x in enumerate(keys):\n",
    "            temp = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                if keys[j] + keys[k] < temp:\n",
    "                    j += 1\n",
    "                elif keys[j] + keys[k] > temp:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    if i < j < k:\n",
    "                        res += nums[x] * nums[keys[j]] * nums[keys[k]]\n",
    "                    elif i == j < k:\n",
    "                        res += nums[x] * (nums[x] - 1) // 2 * nums[keys[k]]\n",
    "                    elif i < j == k:\n",
    "                        res += nums[x] * nums[keys[j]] * (nums[keys[j]] - 1) // 2\n",
    "                    else:\n",
    "                        res += nums[x] * (nums[x] - 1) * (nums[x] - 2) // 6\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "        return res % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MOD = 10**9 + 7\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        cnt = Counter(arr)\n",
    "        nums = sorted(list(cnt.keys()))\n",
    "        n = len(nums)\n",
    "        ans = 0\n",
    "\n",
    "        # 123组合\n",
    "        for i in range(n - 1):\n",
    "            x = nums[i]\n",
    "            for j in range(i + 1, n):\n",
    "                y = nums[j]\n",
    "                z = target - x - y\n",
    "                if z > y:\n",
    "                    ans += cnt[x] * cnt[y] * cnt[z]\n",
    "                    ans %= MOD\n",
    "                else:\n",
    "                    break\n",
    "\n",
    "        # 122组合\n",
    "        for i in range(n):\n",
    "            x = nums[i]\n",
    "            if (target - x) % 2 == 0:\n",
    "                y = (target - x) // 2\n",
    "                if y != x:\n",
    "                    ans += cnt[x] * cnt[y] * (cnt[y] - 1) // 2\n",
    "                    ans %= MOD\n",
    "\n",
    "        # 111组合\n",
    "        if target % 3 == 0:\n",
    "            x = target // 3\n",
    "            ans += cnt[x] * (cnt[x] - 1) * (cnt[x] - 2) // 6\n",
    "            ans %= MOD\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        ans = 0\n",
    "        for i,a in enumerate(arr):\n",
    "            j,k = i + 1,n - 1\n",
    "            while j < k:\n",
    "                t = a + arr[j] + arr[k]\n",
    "                if t == target:\n",
    "                    if arr[j] == arr[k]:\n",
    "                        ans += comb((k - j + 1),2) % MOD\n",
    "                        ans %= MOD\n",
    "                        break\n",
    "                    else:\n",
    "                        l = j\n",
    "                        while l < k and arr[l] == arr[j]:\n",
    "                            l += 1\n",
    "                        r = k\n",
    "                        while j < r and arr[r] == arr[k]:\n",
    "                            r -= 1\n",
    "                        ans += (l - j)*(k - r) % MOD\n",
    "                        ans %= MOD\n",
    "                        j,k = l,r\n",
    "                elif t > target:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    j += 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(arr)\n",
    "        keys = sorted(count)\n",
    "        \n",
    "        ans = 0\n",
    "        \n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                    \n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)  # 频率\n",
    "        keys = sorted(count)  # key排序\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) // 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) // 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) // 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return ans % MOD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, nums: List[int], target: int) -> int:\n",
    "        ans = 0\n",
    "        MOD = 1000000007\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        for i in range(n-2):\n",
    "            l, r = i+1, n-1\n",
    "            while l < r:\n",
    "                # print(l, r)\n",
    "                t = nums[i]+nums[l]+nums[r]\n",
    "                if t < target:\n",
    "                    l += 1\n",
    "                elif t > target:\n",
    "                    r -= 1\n",
    "                elif nums[l] != nums[r]:\n",
    "                    ln, rn = 1, 1\n",
    "                    while l < r and nums[l] == nums[l+1]:\n",
    "                        l += 1\n",
    "                        ln += 1\n",
    "                    while l < r and nums[r] == nums[r-1]:\n",
    "                        r -= 1\n",
    "                        rn += 1\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                    ans += ln*rn\n",
    "                    ans %= MOD\n",
    "                else:\n",
    "                    m = r-l+1\n",
    "                    ans += m*(m-1) // 2\n",
    "                    ans %= MOD\n",
    "                    l = r\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        if len(arr) < 3:\n",
    "            return 0\n",
    "        arr.sort()\n",
    "        res = 0\n",
    "        for i in range(len(arr) - 2):\n",
    "            left = i + 1\n",
    "            right = len(arr) - 1\n",
    "            while(left < right):\n",
    "                flag = 0\n",
    "                total = arr[i] + arr[left] + arr[right]\n",
    "                if total > target:\n",
    "                    right -= 1\n",
    "                elif total < target:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    t1 = 1\n",
    "                    t2 = 1\n",
    "                    if arr[left] == arr[right]:\n",
    "                        res += (right - left + 1) * (right - left) // 2\n",
    "                        break\n",
    "                    while arr[left] == arr[left+1] and left + 1 <= right:\n",
    "                        t1 += 1\n",
    "                        left += 1\n",
    "                    while arr[right] == arr[right-1] and right - 1 >= left:\n",
    "                        t2 += 1\n",
    "                        right -= 1\n",
    "                    res += t1 * t2\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return res % (10 ** 9 +7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        res = 0\n",
    "        mod = 10**9 + 7\n",
    "        for i in range(len(arr)):\n",
    "            left = i + 1\n",
    "            right = len(arr) - 1\n",
    "            t = target - arr[i]\n",
    "            \n",
    "            while left < right:\n",
    "                if arr[left] + arr[right] < t:\n",
    "                    left += 1\n",
    "                elif arr[left] + arr[right] > t:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    if arr[left] == arr[right]:\n",
    "                        count = right - left + 1\n",
    "                        res += count * (count-1) // 2\n",
    "                        break\n",
    "                    else:\n",
    "                        countleft = 1\n",
    "                        while left + 1 < right and arr[left] == arr[left+1]:\n",
    "                            countleft += 1\n",
    "                            left += 1\n",
    "                        countright = 1\n",
    "                        while left < right - 1 and arr[right] == arr[right-1]:\n",
    "                            countright += 1\n",
    "                            right -= 1\n",
    "\n",
    "                        res += countleft * countright\n",
    "                        left += 1\n",
    "                        right -= 1\n",
    "            \n",
    "        return res % mod"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        res = 0\n",
    "        di = dict()\n",
    "        for num in arr:\n",
    "            di[num] = di.get(num, 0) + 1\n",
    "        for i in range(target + 1):\n",
    "            if i in di:\n",
    "                for j in range(i, target + 1):\n",
    "                    if j in di:\n",
    "                        k = target - i - j\n",
    "                        if k >= j and k in di:\n",
    "                            if i == j and j == k:   \n",
    "                                res += di[i] * (di[i] - 1) * (di[i] - 2) // 6\n",
    "                            elif i == j and j != k: \n",
    "                                res += di[i] * (di[i] - 1) // 2 * di[k]\n",
    "                            elif i != j and j == k:\n",
    "                                res += di[i] * di[j] * (di[j] - 1) // 2\n",
    "                            else:\n",
    "                                res += di[i] * di[j] * di[k]\n",
    "        return res % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        mod = 1000000007\n",
    "        ans = 0\n",
    "        for i in range(n):\n",
    "            t2 = target - arr[i]\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            while j < k:\n",
    "                if arr[j] + arr[k] < t2:\n",
    "                    j += 1\n",
    "                elif arr[j] + arr[k] > t2:\n",
    "                    k -= 1\n",
    "                else: # equals t2\n",
    "                    if arr[j] != arr[k]:\n",
    "                        left = 1\n",
    "                        right = 1\n",
    "                        while j + 1 < k and arr[j] == arr[j + 1]:\n",
    "                            j += 1\n",
    "                            left += 1\n",
    "                        while j < k - 1 and arr[k - 1] == arr[k]:\n",
    "                            k -= 1\n",
    "                            right += 1\n",
    "                        ans += left * right\n",
    "                        ans %= mod\n",
    "                        j += 1\n",
    "                        k -= 1\n",
    "                        \n",
    "                    else: # [j~k] are all the same N!/((N-2))!(2)\n",
    "                        N = k - j + 1\n",
    "                        ans += (N * (N - 1) / 2)\n",
    "                        ans %= mod\n",
    "                        break\n",
    "                    \n",
    "        return int(ans)\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        times = {}\n",
    "        arr.sort()\n",
    "        mod = 10**9 + 7\n",
    "        for i in arr:\n",
    "            if i not in times.keys():\n",
    "                times[i] = 1\n",
    "            else:\n",
    "                times[i]+=1\n",
    "        res = 0\n",
    "        for i in range(len(arr)):\n",
    "            times[arr[i]]-=1\n",
    "            l = i+1\n",
    "            r = len(arr)-1\n",
    "            while l<r:\n",
    "                if arr[i]+arr[l]+arr[r]==target:\n",
    "                    if arr[l]!=arr[r]:\n",
    "                        res+=times[arr[l]]*times[arr[r]]\n",
    "                        l+=times[arr[l]]\n",
    "                        r-=times[arr[r]]\n",
    "                        res=res%mod\n",
    "                    \n",
    "                    else:\n",
    "                        res+=(times[arr[l]]-1)*times[arr[l]]//2\n",
    "                        res = res%mod\n",
    "                        break\n",
    "                    \n",
    "                elif arr[i]+arr[l]+arr[r]>target:\n",
    "                    r-=1\n",
    "                elif arr[i]+arr[l]+arr[r]<target:\n",
    "                    l+=1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MOD = 10**9 + 7\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        a = {}\n",
    "        for ar in arr:\n",
    "            if ar in a:\n",
    "                a[ar] += 1\n",
    "            else:\n",
    "                a[ar] = 1\n",
    "        nums = list(a.keys())\n",
    "        nums.sort()\n",
    "        res = 0\n",
    "        if target % 3 == 0:\n",
    "            k = target//3\n",
    "            if k in a:\n",
    "                if a[k] >=3:\n",
    "                    res = (res + (a[k]-2)*(a[k]-1)*a[k]//6) % MOD \n",
    "\n",
    "        for num in nums:\n",
    "            if a[num] >= 2:\n",
    "                k = target - num*2\n",
    "                if k in nums and k != num:\n",
    "                    res = (res + (a[num]-1)*a[num]//2*a[k]) % MOD\n",
    "\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            for j in range(i+1,n):\n",
    "                k = target - nums[i] - nums[j]\n",
    "                if k > nums[j] and k in nums:\n",
    "                    res = (res + a[nums[i]]*a[nums[j]]*a[k]) % MOD\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MOD=10**9+7\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        #时间复杂度O(n^2)\n",
    "        arr.sort()\n",
    "        n=len(arr)\n",
    "        ans=0\n",
    "        for i in range(n):\n",
    "            x=defaultdict(int)\n",
    "            cur=target-arr[i]\n",
    "            #两数之和操作\n",
    "            for j in range(i+1,n):\n",
    "                ans+=x[arr[j]]\n",
    "                x[cur-arr[j]]+=1\n",
    "        return ans%MOD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import collections\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        # 三数之和 = 枚举一数+二数之和\n",
    "        arr.sort()\n",
    "        mod = 10**9+7\n",
    "        ans = 0\n",
    "        for i,x in enumerate(arr):\n",
    "            T = target - x\n",
    "            # 双指针两数之和\n",
    "            j = i+1\n",
    "            k = len(arr)-1\n",
    "            while j < k:\n",
    "                if arr[j] + arr[k] > T:\n",
    "                    k -= 1\n",
    "                elif arr[j] + arr[k] < T:\n",
    "                    j += 1\n",
    "                # arr[j] + arr[k] = T 可分为两种情况 arr[j] != arr[k],arr[j] = arr[k]\n",
    "                elif arr[j] != arr[k]:\n",
    "                    # 统计左边相同值的个数\n",
    "                    c_l = 1\n",
    "                    while j + 1 < k and arr[j] == arr[j+1]:\n",
    "                        c_l += 1\n",
    "                        j += 1\n",
    "                    # 统计右边相同值的个数\n",
    "                    c_r = 1\n",
    "                    while k - 1 > j and arr[k] == arr[k-1]:\n",
    "                        c_r += 1\n",
    "                        k -= 1\n",
    "                    ans += c_l*c_r\n",
    "                    k -= 1\n",
    "                    j += 1\n",
    "                else:\n",
    "                    ans += (k-j+1)*(k-j)//2\n",
    "                    break\n",
    "        return ans%mod"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        cnt = collections.Counter(arr)\n",
    "        nums = sorted(cnt)\n",
    "        ans = 0\n",
    "        for k, kv in enumerate(nums):\n",
    "            l, r = 0, k\n",
    "            while l <= r:\n",
    "                if nums[l] + nums[r] + kv < target:\n",
    "                    l += 1\n",
    "                elif nums[l] + nums[r] + kv > target:\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    if l < r < k:\n",
    "                        ans += cnt[nums[l]] * cnt[nums[r]] * cnt[kv]\n",
    "                    elif l == r < k:\n",
    "                        ans += cnt[nums[l]] * (cnt[nums[l]] - 1) / 2 * cnt[kv]\n",
    "                    elif l < r == k:\n",
    "                        ans += cnt[kv] * (cnt[kv] - 1) / 2 * cnt[nums[l]]\n",
    "                    else:\n",
    "                        ans += cnt[kv] * (cnt[kv] - 1) * (cnt[kv] - 2) / 6\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "        return int(ans) % MOD\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        # 如果直接枚举 i,j,k,时间复杂度为O(n**3)\n",
    "        # 那么需要优化\n",
    "        # 然后有一个O(n)的双指针方法求 arr[j] + arr[k] == target的方法\n",
    "        # 融合这两个方法可以得到一个时间复杂度为O(n**2)的方法\n",
    "        arr.sort()\n",
    "        res = 0\n",
    "        for i,x in enumerate(arr):\n",
    "            T = target - x\n",
    "            j = i+1\n",
    "            k = len(arr)-1\n",
    "            # 双指针模板\n",
    "            while j < k:\n",
    "                if arr[j] + arr[k] > T:\n",
    "                    k -= 1\n",
    "                elif arr[j] + arr[k] < T:\n",
    "                    j += 1\n",
    "                # arr[j] + arr[k] = T 拆分为两种情况\n",
    "                elif arr[j] != arr[k]:\n",
    "                    # 统计左边相同的个数\n",
    "                    left = 1\n",
    "                    while j+1 < k and arr[j] == arr[j+1]:\n",
    "                        j += 1\n",
    "                        left += 1\n",
    "                    # 统计右边相同的个数\n",
    "                    right = 1\n",
    "                    while k-1 > j and arr[k] == arr[k-1]:\n",
    "                        k -= 1\n",
    "                        right += 1\n",
    "                    # 统计一下结果\n",
    "                    res += left*right\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    res += (k-j+1)*(k-j)//2\n",
    "                    break\n",
    "        return res%(10**9+7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        count = 0\n",
    "        n = len(arr)\n",
    "        arr.sort()\n",
    "        mod = 10**9 + 7\n",
    "\n",
    "        for i in range(n):\n",
    "            t = target - arr[i]\n",
    "            j, k = i + 1, n - 1\n",
    "\n",
    "            while j < k:\n",
    "                if arr[j] + arr[k] < t:\n",
    "                    j += 1\n",
    "                elif arr[j] + arr[k] > t:\n",
    "                    k -= 1\n",
    "                elif arr[j] != arr[k]:\n",
    "                    left = right = 1\n",
    "                    while j + 1 < k and arr[j] == arr[j + 1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                    while k - 1 > j and arr[k] == arr[k - 1]:\n",
    "                        right += 1\n",
    "                        k -= 1\n",
    "                    count += left * right\n",
    "                    count %= mod\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    count += (k - j + 1) * (k - j) // 2\n",
    "                    count %= mod\n",
    "                    break\n",
    "        return count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        cnt = collections.Counter(arr)  # 把相同的数字压缩\n",
    "        nums = sorted(cnt)  # 不同的数字列表\n",
    "        ans = 0\n",
    "        for k, kv in enumerate(nums): # 枚举第3个数\n",
    "            l, r = 0, k  # 由于数字可以相同，所以可以重合\n",
    "            while l <= r:  # 由于数字可以相同，所以可以重合\n",
    "                if nums[l] + nums[r] + kv < target:\n",
    "                    l += 1\n",
    "                elif nums[l] + nums[r] + kv > target:\n",
    "                    r -= 1\n",
    "                else: # 分类讨论，相等时的情况\n",
    "                    if l < r < k: # 三个都不同\n",
    "                        ans += cnt[nums[l]] * cnt[nums[r]] * cnt[kv]\n",
    "                    elif l == r < k: # 有两个相同Cn2\n",
    "                        ans += cnt[nums[l]] * (cnt[nums[l]] - 1) / 2 * cnt[kv]\n",
    "                    elif l < r == k: # 有两个相同Cn2\n",
    "                        ans += cnt[kv] * (cnt[kv] - 1) / 2 * cnt[nums[l]]\n",
    "                    else: # 都相同Cn3\n",
    "                        ans += cnt[kv] * (cnt[kv] - 1) * (cnt[kv] - 2) / 6\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "        return int(ans) % MOD\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        dp = [[0, 0, 0, 0] for _ in range(target + 1)]\n",
    "        dp[0][0] = 1\n",
    "        for i in arr:\n",
    "            for j in range(target, i - 1, -1):\n",
    "                for k in range(3, 0, -1):\n",
    "                    dp[j][k] += dp[j - i][k - 1]\n",
    "        return dp[-1][-1] % (10 ** 9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        cnt = collections.Counter(arr)  # 把相同的数字压缩\n",
    "        nums = sorted(cnt)  # 不同的数字列表\n",
    "        ans = 0\n",
    "        for k, kv in enumerate(nums): # 枚举第3个数\n",
    "            l, r = 0, k  # 由于数字可以相同，所以可以重合\n",
    "            while l <= r:  # 由于数字可以相同，所以可以重合\n",
    "                if nums[l] + nums[r] + kv < target:\n",
    "                    l += 1\n",
    "                elif nums[l] + nums[r] + kv > target:\n",
    "                    r -= 1\n",
    "                else: # 分类讨论，相等时的情况\n",
    "                    if l != r != k: # 三个都不同\n",
    "                        ans += cnt[nums[l]] * cnt[nums[r]] * cnt[kv]\n",
    "                    elif l == r != k: # 有两个相同Cn2\n",
    "                        ans += cnt[nums[l]] * (cnt[nums[l]] - 1) / 2 * cnt[kv]\n",
    "                    elif l != r == k: # 有两个相同Cn2\n",
    "                        ans += cnt[kv] * (cnt[kv] - 1) / 2 * cnt[nums[l]]\n",
    "                    else: # 都相同Cn3\n",
    "                        ans += cnt[kv] * (cnt[kv] - 1) * (cnt[kv] - 2) / 6\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "        return int(ans) % MOD\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        n = len(arr)\n",
    "        ans = 0\n",
    "        MOD = 10**9 + 7\n",
    "        arr.sort()\n",
    "        for k in range(2, n):\n",
    "            l, r = 0, k - 1\n",
    "            while l < r:\n",
    "                if arr[l] + arr[r] + arr[k] == target:\n",
    "                    i, j = l, r\n",
    "                    if arr[l] == arr[r]:  # 如果两个指向相等元素，则为Cn2\n",
    "                        ans = (ans + (r - l) * (r - l + 1) // 2) % MOD\n",
    "                        break\n",
    "                    while arr[i] == arr[l]: i += 1\n",
    "                    while arr[j] == arr[r]: j -= 1\n",
    "                    ans = (ans + (i - l) * (r - j)) % MOD  # 两个元素不同，则为x*y\n",
    "                    l, r = i, j\n",
    "                elif arr[l] + arr[r] + arr[k] < target:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(arr)\n",
    "        keys = sorted(count)\n",
    "        \n",
    "        ans = 0\n",
    "        \n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                    \n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = [0] * 101\n",
    "        unique_nums = 0\n",
    "        for num in arr:\n",
    "            count[num] += 1\n",
    "            if count[num] == 1:\n",
    "                unique_nums += 1\n",
    "        \n",
    "        keys = []\n",
    "        for idx, num in enumerate(count):\n",
    "            if num > 0:\n",
    "                keys.append(idx)\n",
    "        \n",
    "        res = 0\n",
    "        for i in range(len(keys)):\n",
    "            a = keys[i]\n",
    "            T = target - a\n",
    "            left, right = i, len(keys) - 1\n",
    "            \n",
    "            while left <= right:\n",
    "                b, c = keys[left], keys[right]\n",
    "                \n",
    "                if b + c < T:\n",
    "                    left += 1\n",
    "                elif b + c > T:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    if i < left < right:\n",
    "                        res += count[a] * count[b] * count[c]\n",
    "                    elif i == left < right:\n",
    "                        res += count[a] * (count[a] - 1) // 2 * count[c]\n",
    "                    elif i < left == right:\n",
    "                        res += count[a] * count[b] * (count[b] - 1) // 2\n",
    "                    else:\n",
    "                        res += count[a] * (count[a] - 1) * (count[a] - 2) // 6\n",
    "                    \n",
    "                    res %= MOD\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        \n",
    "        return res % MOD\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9+7\n",
    "        ans = 0\n",
    "        A.sort()\n",
    "\n",
    "        for i,x in enumerate(A):\n",
    "            j,k = i+1, len(A) -1\n",
    "            T = target - A[i]\n",
    "\n",
    "            while j < k:\n",
    "                if A[j]+A[k] < T:\n",
    "                    j += 1\n",
    "                elif A[j] + A[k] > T:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    if A[j] == A[k]:\n",
    "                        ans += (k-j+1)*(k-j)/2\n",
    "                        ans %= MOD\n",
    "                        break\n",
    "                    left = right = 1\n",
    "                    while j+1 < k and A[j] == A[j+1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                        # print(i,j,k)\n",
    "                    while j < k-1 and A[k-1] == A[k]:\n",
    "                        right += 1\n",
    "                        k -=1\n",
    "\n",
    "                    # print(left*right)\n",
    "                    ans += left*right\n",
    "                    ans %= MOD\n",
    "                    j+=1\n",
    "                    k-=1\n",
    "        return int(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "'''\n",
    "三指针\n",
    "两数之和，双指针可行\n",
    "\n",
    "'''\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        ans = 0\n",
    "        A.sort()  # 排序\n",
    "\n",
    "        for i, x in enumerate(A):\n",
    "            # We'll try to find the number of i < j < k\n",
    "            # with A[j] + A[k] == T, where T = target - A[i].\n",
    "\n",
    "            # The below is a \"two sum with multiplicity\".\n",
    "            T = target - A[i]\n",
    "            j, k = i+1, len(A) - 1\n",
    "\n",
    "            while j < k:\n",
    "                # These steps proceed as in a typical two-sum.\n",
    "                if A[j] + A[k] < T:\n",
    "                    j += 1\n",
    "                elif A[j] + A[k] > T:\n",
    "                    k -= 1\n",
    "                # These steps differ:\n",
    "                elif A[j] != A[k]: # We have A[j] + A[k] == T.\n",
    "                    # Let's count \"left\": the number of A[j] == A[j+1] == A[j+2] == ...\n",
    "                    # And similarly for \"right\".\n",
    "                    left = right = 1\n",
    "                    while j + 1 < k and A[j] == A[j+1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                    while k - 1 > j and A[k] == A[k-1]:\n",
    "                        right += 1\n",
    "                        k -= 1\n",
    "\n",
    "                    # We contributed left * right many pairs.\n",
    "                    ans += left * right\n",
    "                    ans %= MOD\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "                else:\n",
    "                    # M = k - j + 1\n",
    "                    # We contributed M * (M-1) / 2 pairs.\n",
    "                    ans += (k-j+1) * (k-j) // 2\n",
    "                    ans %= MOD\n",
    "                    break\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr, target):\n",
    "        arr.sort()\n",
    "        cnt = 0\n",
    "        MOD = 10**9 + 7\n",
    "\n",
    "        for i in range(0, len(arr)):\n",
    "            left_p = i + 1\n",
    "            right_p = len(arr) - 1\n",
    "\n",
    "            while right_p > left_p:\n",
    "                if arr[i] + arr[left_p] + arr[right_p] == target: \n",
    "                    if arr[left_p] == arr[right_p]:\n",
    "                        cnt += (right_p - left_p) * (right_p - left_p + 1) / 2\n",
    "                        break\n",
    "                    else:\n",
    "                        l_c = 1\n",
    "                        r_c = 1\n",
    "                        while arr[left_p + 1] == arr[left_p]:\n",
    "                            l_c += 1\n",
    "                            left_p += 1\n",
    "                        \n",
    "                        while arr[right_p - 1] == arr[right_p]:\n",
    "                            r_c += 1\n",
    "                            right_p -= 1 \n",
    "                        \n",
    "                        cnt += l_c * r_c\n",
    "                        left_p += 1\n",
    "                        right_p -= 1\n",
    "                elif arr[i] + arr[left_p] + arr[right_p] > target:\n",
    "                    right_p -= 1\n",
    "                else:\n",
    "                    left_p += 1\n",
    "        \n",
    "        res = int(cnt) % MOD\n",
    "        return res\n",
    "            \n",
    "if __name__ == \"__main__\":\n",
    "    arr = [1,1,2,2,3,3,4,4,5,5]\n",
    "    target = 8\n",
    "    print(Solution().threeSumMulti(arr, target))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9+7\n",
    "        ans = 0\n",
    "        dic = collections.Counter(arr)\n",
    "        sortedDic = sorted(dic.items())\n",
    "        n = len(sortedDic)\n",
    "\n",
    "        for i, (num, cnt) in enumerate(sortedDic):\n",
    "            twoSum = target-num\n",
    "            j, k = i+1, n-1\n",
    "            if sortedDic[i][0] * 3 == target and sortedDic[i][1]>=3:\n",
    "                ans += sortedDic[i][1] * (sortedDic[i][1]-1)* (sortedDic[i][1]-2)/6\n",
    "                ans %= MOD\n",
    "\n",
    "            while j<=k:\n",
    "                if sortedDic[j][0] + sortedDic[k][0] < twoSum:\n",
    "                    j += 1\n",
    "                elif sortedDic[j][0] + sortedDic[k][0] > twoSum:\n",
    "                    k -= 1\n",
    "                elif j<k:\n",
    "                    ans += sortedDic[j][1] * sortedDic[k][1]*cnt\n",
    "                    ans %= MOD\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    ans += cnt*sortedDic[j][1] *(sortedDic[j][1]-1) / 2\n",
    "                    ans %= MOD\n",
    "                    break\n",
    "\n",
    "            if cnt >= 2:\n",
    "                j = i+1\n",
    "                while j<n:\n",
    "                    total = 2*num + sortedDic[j][0]\n",
    "                    if total > target:\n",
    "                        break\n",
    "                    elif total <target:\n",
    "                        j += 1\n",
    "                    else:\n",
    "                        ans += sortedDic[j][1] *cnt * (cnt-1) /2\n",
    "                        ans %= MOD\n",
    "                        break\n",
    "            \n",
    "        return int(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        cnt = Counter(arr)\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        mod = 10**9+7       \n",
    "        ans = 0\n",
    "        for i in range(n-2):\n",
    "            cnt[arr[i]] -= 1\n",
    "            g = cnt.copy()\n",
    "            for j in range(i+1,n-1):\n",
    "                # print(g,cnt)\n",
    "                g[arr[j]] -= 1\n",
    "                t = target - arr[i] - arr[j]\n",
    "                if t < arr[0]:\n",
    "                    break\n",
    "                ans += g[t]%mod\n",
    "        return ans%mod\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MOD=10**9+7\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        n=len(arr)\n",
    "        ans=0\n",
    "        for i in range(n):\n",
    "            x=defaultdict(int)\n",
    "            cur=target-arr[i]\n",
    "            #两数之和操作\n",
    "            for j in range(i+1,n):\n",
    "                ans+=x[arr[j]]\n",
    "                x[cur-arr[j]]+=1\n",
    "        return ans%MOD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MOD=10**9+7\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        n=len(arr)\n",
    "        ans=0\n",
    "        for i in range(n):\n",
    "            x=defaultdict(int)\n",
    "            cur=target-arr[i]\n",
    "            #两数之和操作\n",
    "            for j in range(i+1,n):\n",
    "                ans+=x[arr[j]]\n",
    "                x[cur-arr[j]]+=1\n",
    "        return ans%MOD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        mod = 10**9 + 7\n",
    "        ans, count, nums = 0, {}, []\n",
    "        for a in arr:\n",
    "            if a not in count:\n",
    "                count[a] = 0\n",
    "                nums.append(a)\n",
    "            count[a] += 1\n",
    "        \n",
    "        nums = sorted(nums)\n",
    "        n = len(nums)\n",
    "\n",
    "        for i in range(0, n - 2):\n",
    "            if nums[i] > target:\n",
    "                break\n",
    "            for j in range(i+1, n - 1):\n",
    "                if nums[i] + nums[j] > target:\n",
    "                    break\n",
    "                for k in range(j+1, n):\n",
    "                    if nums[i] + nums[j] + nums[k] == target:\n",
    "                        ans += count[nums[i]] * count[nums[j]] * count[nums[k]]\n",
    "                        ans %= mod\n",
    "                        break\n",
    "\n",
    "        for i in range(0, n - 1):\n",
    "            if nums[i] > target:\n",
    "                break\n",
    "            if count[nums[i]] > 1:\n",
    "                if nums[i] * 2 > target:\n",
    "                    break\n",
    "                for j in range(i+1, n):\n",
    "                    if nums[i] * 2 + nums[j] == target:\n",
    "                        x = math.comb(count[nums[i]], 2)\n",
    "                        ans += x * count[nums[j]]\n",
    "                        ans %= mod\n",
    "            for j in range(i+1, n):\n",
    "                if count[nums[j]] > 1 and nums[i] + nums[j] * 2 == target:\n",
    "                    x = math.comb(count[nums[j]], 2)\n",
    "                    ans += count[nums[i]] * x\n",
    "                    ans %= mod\n",
    "        \n",
    "        for i in range(0, n):\n",
    "            if count[nums[i]] > 2 and nums[i] * 3 == target:\n",
    "                ans += math.comb(count[nums[i]], 3)\n",
    "                ans %= mod\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        ans = 0\n",
    "        A.sort()\n",
    "\n",
    "        for i, x in enumerate(A):\n",
    "            # We'll try to find the number of i < j < k\n",
    "            # with A[j] + A[k] == T, where T = target - A[i].\n",
    "\n",
    "            # The below is a \"two sum with multiplicity\".\n",
    "            T = target - A[i]\n",
    "            j, k = i+1, len(A) - 1\n",
    "\n",
    "            while j < k:\n",
    "                # These steps proceed as in a typical two-sum.\n",
    "                if A[j] + A[k] < T:\n",
    "                    j += 1\n",
    "                elif A[j] + A[k] > T:\n",
    "                    k -= 1\n",
    "                # These steps differ:\n",
    "                elif A[j] != A[k]: # We have A[j] + A[k] == T.\n",
    "                    # Let's count \"left\": the number of A[j] == A[j+1] == A[j+2] == ...\n",
    "                    # And similarly for \"right\".\n",
    "                    left = right = 1\n",
    "                    while j + 1 < k and A[j] == A[j+1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                    while k - 1 > j and A[k] == A[k-1]:\n",
    "                        right += 1\n",
    "                        k -= 1\n",
    "\n",
    "                    # We contributed left * right many pairs.\n",
    "                    ans += left * right\n",
    "                    ans %= MOD\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "                else:\n",
    "                    # M = k - j + 1\n",
    "                    # We contributed M * (M-1) / 2 pairs.\n",
    "                    ans += (k-j+1) * (k-j) / 2\n",
    "                    ans %= MOD\n",
    "                    break\n",
    "\n",
    "        return int(ans)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        cnt = Counter(arr)\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        mod = 10**9+7\n",
    "        # visit = set()\n",
    "        \n",
    "        ans = 0\n",
    "        for i in range(n-2):\n",
    "            cnt[arr[i]] -= 1\n",
    "            g = cnt.copy()\n",
    "            for j in range(i+1,n-1):\n",
    "                # print(g,cnt)\n",
    "                g[arr[j]] -= 1\n",
    "                t = target - arr[i] - arr[j]\n",
    "                if t < 0:\n",
    "                    break\n",
    "                # com = tuple(sorted([arr[i],arr[j],t]))\n",
    "                # print(arr[i],arr[j],t,cnt[t])\n",
    "                ans += g[t]%mod\n",
    "                # if g[t]:\n",
    "                #     ans += g[t]\n",
    "                #     ans %= mod\n",
    "                    # visit.add(com)\n",
    "                    # print(arr[i],arr[j],t,cnt[t])\n",
    "                # if t != arr[i] and t != arr[j]:\n",
    "                #     ans += cnt[t]\n",
    "                # elif t == arr[i] and t == arr[j]:\n",
    "                #     ans += cnt[t] - 2\n",
    "                # else:\n",
    "                #     ans += cnt[t] - 1\n",
    "                # ans %= mod\n",
    "        return ans%mod\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        n = len(A)\n",
    "        A.sort()\n",
    "        first_idx, last_idx = {}, {}\n",
    "        for i, num in enumerate(A):\n",
    "            if num not in first_idx:\n",
    "                first_idx[num] = i\n",
    "            last_idx[num] = i  # 记录排序后，0-9最后出现的位置\n",
    "        ans = 0\n",
    "\n",
    "        for first in range(n - 2):  # 枚举第一个元素\n",
    "            second, third = first + 1, n - 1\n",
    "            two_target = target - A[first]\n",
    "            while second < third:\n",
    "                s = A[second] + A[third]\n",
    "                if s > two_target:  # 当前数值太大\n",
    "                    third -= 1\n",
    "                elif s < two_target:  # 当前数值太小\n",
    "                    second += 1\n",
    "                else:  # 遇到一个组合能够满足了\n",
    "                    if A[second] == A[third]:\n",
    "                        num_second = last_idx[A[third]] - max(second, first) + 1\n",
    "                        ans += num_second * (num_second-1) // 2 # 这个组合的数量\n",
    "                        break                                   # 直接枚举第二个first\n",
    "                    else:\n",
    "                        num_second = last_idx[A[second]] - max(second, first) + 1\n",
    "                        num_third = third - first_idx[A[third]] + 1\n",
    "                        ans = ans + num_second * num_third  # 这个组合的数量\n",
    "                        third = first_idx[A[third]] - 1     # 重新赋值\n",
    "                        second = last_idx[A[second]] + 1            \n",
    "        ans %= MOD\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        mp = defaultdict(int)\n",
    "        ans = 0\n",
    "        n = len(arr)\n",
    "        mod = 10 ** 9 + 7\n",
    "        for i in range(n):\n",
    "            mp.clear()\n",
    "            t = target - arr [i]\n",
    "            for j in range(i + 1, n):\n",
    "                if t - arr[j] in mp:\n",
    "                    ans = (ans + mp[t - arr[j]]) % mod\n",
    "                mp[arr[j]] += 1\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        ans = 0\n",
    "        x = Counter(arr)\n",
    "        arr = sorted(list(set(arr)))\n",
    "\n",
    "        for i in range(len(arr)):\n",
    "            for j in range(i + 1, len(arr)):\n",
    "                if arr[i] + arr[j] > target:\n",
    "                    break\n",
    "                k = target - arr[i] - arr[j]\n",
    "                if k > arr[j]:\n",
    "                    ans += x[arr[i]] * x[arr[j]] * x[k]\n",
    "\n",
    "        for i in x:\n",
    "            if x[i] == 1:\n",
    "                continue\n",
    "            j = target - 2 * i\n",
    "            if i != j and j in x:\n",
    "                ans += ((x[i] * (x[i] - 1)) // 2) * x[j]\n",
    "        \n",
    "        s = target // 3\n",
    "        if s in x and x[s] >= 3 and target % 3 == 0:\n",
    "            ans += (x[s] * (x[s] - 1) * (x[s] - 2)) // 6\n",
    "        \n",
    "        return ans % (10**9 + 7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        res = 0\n",
    "        n = len(arr)\n",
    "        for i in range(n):\n",
    "            if arr[i] > target:\n",
    "                continue\n",
    "            tmp = target - arr[i]\n",
    "            d = {}\n",
    "            for j in range(i+1,n):\n",
    "                if arr[j] > tmp:\n",
    "                    continue\n",
    "                else:\n",
    "                    if (tmp - arr[j]) in d:\n",
    "                        res = (res+d[tmp-arr[j]])%1000000007\n",
    "                    if arr[j] in d:\n",
    "                        d[arr[j]] += 1\n",
    "                    else:\n",
    "                        d[arr[j]] = 1\n",
    "        return res\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        mp = {}\n",
    "        for x in arr:\n",
    "            mp[x] = mp.get(x, 0) + 1\n",
    "        # print(mp)\n",
    "        ans, n = 0, len(mp)\n",
    "        nums = [0] * n\n",
    "        i = 0\n",
    "        for x in mp:\n",
    "            nums[i] = x\n",
    "            i+=1\n",
    "        # print('nums : ',nums)\n",
    "\n",
    "        for i in range(n):\n",
    "            l, r = i, n-1\n",
    "            while l<=r:\n",
    "                tmpsum = nums[i] + nums[l] + nums[r]\n",
    "                # print('i:{}, l:{}, r:{}, ans:{}, sum:{}'.format(i, l, r, ans, tmpsum))\n",
    "                if tmpsum > target:\n",
    "                    r-=1\n",
    "                elif tmpsum < target:\n",
    "                    l+=1\n",
    "                else:\n",
    "                    cnt1, cnt2 = 0, 0\n",
    "                    def calcnt(n1, n2)->int:\n",
    "                        cnt1 = mp[nums[n1]]\n",
    "                        cnt2 = mp[nums[n2]]\n",
    "                        # print('cal before [{}, {}]'.format(cnt1,cnt2))\n",
    "                        if cnt1 == 1:\n",
    "                            cnt1 = 0\n",
    "                        elif cnt1 == 2:\n",
    "                            cnt1 = 1\n",
    "                        else:\n",
    "                            cnt1 = comb(cnt1, 2)\n",
    "                        # print('calcnt({}, {}) -> {}'.format(n1, n2, cnt1*cnt2))\n",
    "                        return cnt1 * cnt2\n",
    "                    if (i == l and l != r):\n",
    "                        ans += calcnt(i, r)\n",
    "                    elif (i!=l and l==r):\n",
    "                        ans += calcnt(r, i)\n",
    "                    elif i!=l and l!=r:\n",
    "                        ans += mp[nums[i]] * mp[nums[l]] * mp[nums[r]]\n",
    "                    else: # 三者相等\n",
    "                        # print('i : {}, l : {}, r : {}'.format(i,l,r))\n",
    "                        cnt1 = mp[nums[i]]\n",
    "                        if cnt1 < 3:\n",
    "                            cnt1 = 0\n",
    "                        elif cnt1 == 3:\n",
    "                            cnt1 = 1\n",
    "                        else:\n",
    "                            cnt1 = comb(cnt1, 3)\n",
    "                        ans += cnt1\n",
    "                    l+=1\n",
    "\n",
    "\n",
    "        return ans % (10 ** 9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def modAdd(a, b, modNum):\n",
    "    return ((a % modNum) + (b % modNum)) % modNum\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        modNum = 10**9 + 7\n",
    "        c = Counter(arr)\n",
    "        numLst = sorted(list(c.keys()))\n",
    "        rtnAns = 0\n",
    "        for i in range(len(numLst)):  # 外层指针\n",
    "            innerTarget = target - numLst[i]\n",
    "            j, k = i, len(numLst) - 1\n",
    "            while j <= k:\n",
    "                innerSum = numLst[j] + numLst[k]\n",
    "                match (innerSum>innerTarget) - (innerTarget>innerSum):\n",
    "                    case -1: # <\n",
    "                        j += 1\n",
    "                    case 0:\n",
    "                        if i == j and j == k:\n",
    "                            iCount = c[numLst[i]]\n",
    "                            if iCount >= 3:\n",
    "                                rtnAns = modAdd(rtnAns, (iCount * (iCount - 1) * (iCount -2)) // (3 * 2 * 1), modNum)\n",
    "                                # rtnAns += (iCount * (iCount - 1) * (iCount -2)) // (3 * 2 * 1)\n",
    "                        elif j == k:\n",
    "                            iCount = c[numLst[i]]\n",
    "                            jCount = c[numLst[j]]\n",
    "                            if jCount >= 2:\n",
    "                                rtnAns = modAdd(rtnAns, iCount * ((jCount * (jCount - 1)) // (2 * 1)), modNum)\n",
    "                                # rtnAns += iCount * ((jCount * (jCount - 1)) // (2 * 1))\n",
    "                        elif i == j:\n",
    "                            iCount = c[numLst[i]]\n",
    "                            kCount = c[numLst[k]]\n",
    "                            if iCount >= 2:\n",
    "                                rtnAns = modAdd(rtnAns, ((iCount * (iCount - 1)) // (2 * 1)) * kCount, modNum)\n",
    "                                # rtnAns += ((iCount * (iCount - 1)) // (2 * 1)) * kCount\n",
    "                        elif i == k:\n",
    "                            iCount = c[numLst[i]]\n",
    "                            jCount = c[numLst[j]]\n",
    "                            if iCount >= 2:\n",
    "                                rtnAns = modAdd(rtnAns, ((iCount * (iCount - 1)) // (2 * 1)) * jCount, modNum)\n",
    "                                # rtnAns += ((iCount * (iCount - 1)) // (2 * 1)) * jCount\n",
    "                        else:\n",
    "                            rtnAns = modAdd(rtnAns, c[numLst[i]] * c[numLst[j]] * c[numLst[k]], modNum)\n",
    "                            # rtnAns += c[numLst[i]] * c[numLst[j]] * c[numLst[k]]\n",
    "                        # break 这里不能 break 否则便会找不到所有的可能\n",
    "                        j += 1\n",
    "                        k -= 1\n",
    "                    case 1: # >\n",
    "                        k -= 1\n",
    "        return rtnAns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = [0] * 101\n",
    "        unique_nums = 0\n",
    "        for num in arr:\n",
    "            count[num] += 1\n",
    "            if count[num] == 1:\n",
    "                unique_nums += 1\n",
    "        \n",
    "\n",
    "        keys = []\n",
    "        for x, c in enumerate(count):\n",
    "            if c > 0:\n",
    "                keys.append(x)\n",
    "        \n",
    "        res = 0\n",
    "        for i in range(len(keys)):\n",
    "            a = keys[i]\n",
    "            T = target - a\n",
    "            left, right = i, len(keys) - 1\n",
    "            \n",
    "            while left <= right:\n",
    "                y, z = keys[left], keys[right]\n",
    "                \n",
    "                if y + z < T:\n",
    "                    left += 1\n",
    "                elif y + z > T:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    if i < left < right:\n",
    "                        res += count[a] * count[y] * count[z]\n",
    "                    elif i == left < right:\n",
    "                        res += count[a] * (count[a] - 1) // 2 * count[z]\n",
    "                    elif i < left == right:\n",
    "                        res += count[a] * count[y] * (count[y] - 1) // 2\n",
    "                    else:\n",
    "                        res += count[a] * (count[a] - 1) * (count[a] - 2) // 6\n",
    "                    \n",
    "                    res %= MOD\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        \n",
    "        return res % MOD\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = [0] * 101\n",
    "        unique_nums = 0\n",
    "        for num in arr:\n",
    "            count[num] += 1\n",
    "            if count[num] == 1:\n",
    "                unique_nums += 1\n",
    "        \n",
    "        keys = []\n",
    "        for num, cnt in enumerate(count):\n",
    "            if cnt > 0:\n",
    "                keys.append(num)\n",
    "        \n",
    "        res = 0\n",
    "        for i in range(len(keys)):\n",
    "            a = keys[i]\n",
    "            T = target - a\n",
    "            left, right = i, len(keys) - 1\n",
    "            \n",
    "            while left <= right:\n",
    "                b, c = keys[left], keys[right]\n",
    "                \n",
    "                if b + c < T:\n",
    "                    left += 1\n",
    "                elif b + c > T:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    if i < left < right: # a b c是不同的数字\n",
    "                        res += count[a] * count[b] * count[c]\n",
    "                    elif i == left < right: # a和b相同，c不同\n",
    "                        res += count[a] * (count[a] - 1) // 2 * count[c]\n",
    "                    elif i < left == right: # b和c相同，a不同\n",
    "                        res += count[a] * count[b] * (count[b] - 1) // 2\n",
    "                    else: # a b c相同\n",
    "                        res += count[a] * (count[a] - 1) * (count[a] - 2) // 6\n",
    "                    \n",
    "                    res %= MOD\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        \n",
    "        return res % MOD\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        \"\"\"\n",
    "        arr[j] + arr[k] = target\n",
    "        arr[k] = target - arr[j]\n",
    "        \"\"\"\n",
    "        mp = defaultdict(int)\n",
    "        ans = 0\n",
    "        n = len(arr)\n",
    "        mod = 10 ** 9 + 7\n",
    "        for i in range(n):\n",
    "            mp.clear()\n",
    "            t = target - arr [i]\n",
    "            # print(ans)\n",
    "            for j in range(i + 1, n):\n",
    "                if t - arr[j] in mp:\n",
    "                    ans = (ans + mp[t - arr[j]]) % mod\n",
    "                mp[arr[j]] += 1\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "class Solution:\n",
    "    def find_targe_sum(self, arr, idx, target, selected_num, total):\n",
    "        if idx==len(arr) and total<3:\n",
    "            return\n",
    "        if total==3:\n",
    "            S = 0\n",
    "            result = 1\n",
    "            for num, freq, selected in selected_num:\n",
    "                S += num*selected\n",
    "                result *= math.comb(freq, selected)\n",
    "            if S==target:\n",
    "                self.result = (self.result+result)%(1e9+7)\n",
    "                # print(selected_num, result)\n",
    "            return\n",
    "        num, freq = arr[idx]\n",
    "        self.find_targe_sum(arr, idx+1, target, selected_num, total)\n",
    "        for i in range(1, min(4-total, freq+1)):\n",
    "            selected_num.append((num, freq, i))\n",
    "            self.find_targe_sum(arr, idx+1, target, selected_num, total+i)\n",
    "            selected_num.pop(-1)\n",
    "        return\n",
    "        \n",
    "\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr = sorted(arr)\n",
    "        arr_tuple = {}\n",
    "        for num in arr:\n",
    "            if num not in arr_tuple:\n",
    "                arr_tuple[num] = 1\n",
    "            else:\n",
    "                arr_tuple[num] += 1\n",
    "        arr_tuple = list(arr_tuple.items())\n",
    "        self.result = 0\n",
    "        self.find_targe_sum(arr_tuple, 0, target, [], 0)\n",
    "        return int(self.result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10 ** 9 + 7\n",
    "        cnt = Counter(arr).most_common()\n",
    "        n = len(cnt)\n",
    "        res = 0\n",
    "        for i in range(n):\n",
    "            for j in range(i, n):\n",
    "                if i == j and cnt[i][1] < 2: continue\n",
    "                for k in range(j, n):\n",
    "                    if j == k and cnt[j][1] < 2: continue\n",
    "                    if i == j == k and cnt[i][1] < 3: continue\n",
    "                    if cnt[i][0] + cnt[j][0] + cnt[k][0] == target:\n",
    "                        if i == j == k:\n",
    "                            res += cnt[i][1] * (cnt[i][1] - 1) * (cnt[i][1] - 2) // 6 % MOD\n",
    "                        elif i == j and j != k:\n",
    "                            res += cnt[i][1] * (cnt[i][1] - 1) // 2 * cnt[k][1] % MOD\n",
    "                        elif i == k and j != k:\n",
    "                            res += cnt[i][1] * (cnt[i][1] - 1) // 2 * cnt[j][1] % MOD\n",
    "                        elif j == k and j != i:\n",
    "                            res += cnt[j][1] * (cnt[j][1] - 1) // 2 * cnt[i][1] % MOD\n",
    "                        else:\n",
    "                            res += cnt[i][1] * cnt[j][1] * cnt[k][1] % MOD\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        # 题意：问你从arr中任意选择三个数，这三个数相加的和等于target的组数有多少\n",
    "        # O（n**3)\n",
    "        mod = 10**9+7\n",
    "        ans = 0\n",
    "        arr.sort()\n",
    "        for i,x in enumerate(arr):\n",
    "            T = target - x\n",
    "            j,k = i+1,len(arr)-1\n",
    "\n",
    "            while j < k:\n",
    "                if arr[j] + arr[k] < T:\n",
    "                    j += 1\n",
    "                elif arr[j] + arr[k] > T:\n",
    "                    k -= 1\n",
    "                elif arr[j] != arr[k]:\n",
    "                    left = right = 1\n",
    "                    while j + 1 < k and arr[j] == arr[j+1]:\n",
    "                        left += 1\n",
    "                        j += 1\n",
    "                    while k - 1 > j and arr[k] == arr[k-1]:\n",
    "                        right += 1\n",
    "                        k -= 1\n",
    "                    ans += left * right\n",
    "                    ans %= mod\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    ans += (k-j+1)*(k-j)//2\n",
    "                    ans%mod\n",
    "                    break\n",
    "        return ans%mod"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "      MOD=int(1e9+7)\n",
    "      arr.sort()\n",
    "      def twoSum(start:int,target:int):\n",
    "        nonlocal ret\n",
    "        end=len(arr)-1\n",
    "        while start<end:\n",
    "          if arr[start]+arr[end]<target:\n",
    "            start+=1\n",
    "          elif arr[start]+arr[end]>target:\n",
    "            end-=1\n",
    "          elif arr[start]!=arr[end]:\n",
    "            ss,ee=start,end\n",
    "            while arr[ss]==arr[start]:ss+=1\n",
    "            while arr[ee]==arr[end]:ee-=1\n",
    "            ret+=(ss-start)*(end-ee)\n",
    "            ret%=MOD\n",
    "            start,end=ss,ee\n",
    "          else:\n",
    "            same_len=end-start+1\n",
    "            ret+=same_len*(same_len-1)//2\n",
    "            ret%=MOD\n",
    "            break\n",
    "      ret=0\n",
    "      for i,num in enumerate(arr):\n",
    "        _target=target-num\n",
    "        if _target<2*num: break\n",
    "        twoSum(i+1,_target)\n",
    "      return ret\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        count = Counter(A)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # All different\n",
    "        for x in range(101):\n",
    "            for y in range(x+1, 101):\n",
    "                z = target - x - y\n",
    "                if y < z <= 100:\n",
    "                    ans += count[x] * count[y] * count[z]\n",
    "                    ans %= MOD\n",
    "\n",
    "        # x == y\n",
    "        for x in range(101):\n",
    "            z = target - 2*x\n",
    "            if x < z <= 100:\n",
    "                ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                ans %= MOD\n",
    "\n",
    "        # y == z\n",
    "        for x in range(101):\n",
    "            if (target - x) % 2 == 0:\n",
    "                y = (target - x) // 2\n",
    "                if x < y <= 100:\n",
    "                    ans += count[x] * count[y] * (count[y] - 1) // 2\n",
    "                    ans %= MOD\n",
    "\n",
    "        # x == y == z\n",
    "        if target % 3 == 0:\n",
    "            x = target // 3\n",
    "            if 0 <= x <= 100:\n",
    "                ans += count[x] * (count[x] - 1) * (count[x] - 2) // 6\n",
    "                ans %= MOD\n",
    "        return int(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\r\n",
    "        ans = 0\r\n",
    "        arr = sorted(arr)\r\n",
    "        n = len(arr)\r\n",
    "        for first in range(n):\r\n",
    "            second,third = first+1,n-1\r\n",
    "            while second<third:\r\n",
    "                sums = arr[first]+arr[second]+arr[third]\r\n",
    "                if sums==target:\r\n",
    "                    # ans+=1\r\n",
    "                    # second+=1\r\n",
    "                    if arr[second]==arr[third]:\r\n",
    "                        ans+=(third-second+1)*(third-second)/2\r\n",
    "                        break\r\n",
    "                    t1,t2 = 1,1\r\n",
    "                    while arr[second]==arr[second+1] and second+1<=third:\r\n",
    "                        t1+=1\r\n",
    "                        second+=1\r\n",
    "                    while arr[third]==arr[third-1] and third-1>=second:\r\n",
    "                        t2+=1\r\n",
    "                        third-=1\r\n",
    "                    ans+=(t1*t2)\r\n",
    "                    second+=1\r\n",
    "                    third-=1\r\n",
    "                elif sums>target:\r\n",
    "                    third-=1\r\n",
    "                else:\r\n",
    "                    second+=1\r\n",
    "        return int(ans%(10**9+7))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        mp = Counter(arr)\n",
    "        keys = sorted(mp)\n",
    "        ans, n = 0, len(mp)\n",
    "\n",
    "        for i in range(n):\n",
    "            l, r = i, n-1\n",
    "            while l<=r:\n",
    "                tmpsum = keys[i] + keys[l] + keys[r]\n",
    "                # print('i:{}, l:{}, r:{}, ans:{}, sum:{}'.format(i, l, r, ans, tmpsum))\n",
    "                if tmpsum > target:\n",
    "                    r-=1\n",
    "                elif tmpsum < target:\n",
    "                    l+=1\n",
    "                else:\n",
    "                    cnt1, cnt2 = 0, 0\n",
    "                    def calcnt(n1, n2)->int:\n",
    "                        cnt1 = mp[keys[n1]]\n",
    "                        cnt2 = mp[keys[n2]]\n",
    "                        # print('cal before [{}, {}]'.format(cnt1,cnt2))\n",
    "                        if cnt1 == 1:\n",
    "                            cnt1 = 0\n",
    "                        elif cnt1 == 2:\n",
    "                            cnt1 = 1\n",
    "                        else: # 大于两个数，则进行组合，n选2\n",
    "                            cnt1 = comb(cnt1, 2) \n",
    "                        # print('calcnt({}, {}) -> {}'.format(n1, n2, cnt1*cnt2))\n",
    "                        return cnt1 * cnt2\n",
    "                    if (i == l and l != r): # 左边两个是同一个数\n",
    "                        ans += calcnt(i, r)\n",
    "                    elif (i!=l and l==r): # 右边两个是同一个数\n",
    "                        ans += calcnt(r, i)\n",
    "                    elif i!=l and l!=r: # 指向个不相同\n",
    "                        ans += mp[keys[i]] * mp[keys[l]] * mp[keys[r]]\n",
    "                    else: # 三个指针都指向同一个数\n",
    "                        # print('i : {}, l : {}, r : {}'.format(i,l,r))\n",
    "                        cnt1 = mp[keys[i]]\n",
    "                        if cnt1 < 3:\n",
    "                            cnt1 = 0\n",
    "                        elif cnt1 == 3:\n",
    "                            cnt1 = 1\n",
    "                        else:\n",
    "                            cnt1 = comb(cnt1, 3)\n",
    "                        ans += cnt1\n",
    "                    l+=1 # 哪个指针移动都可以，但是一定要移动\n",
    "\n",
    "\n",
    "        return ans % (10 ** 9 + 7)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        mod = 10**9 + 7\n",
    "\n",
    "        count = Counter(arr)\n",
    "        keys = sorted(count) \n",
    "        len_distinct = len(keys)\n",
    "        res = 0\n",
    "\n",
    "        for left in range(len_distinct):\n",
    "            mid = left\n",
    "            right = len_distinct-1\n",
    "\n",
    "            while mid <= right:\n",
    "                cur_sum = keys[left] + keys[mid] + keys[right]\n",
    "                # print(left, mid, right)\n",
    "\n",
    "                if cur_sum == target:\n",
    "                    if left < mid < right:\n",
    "                        res += count[keys[left]] * count[keys[mid]] * count[keys[right]]\n",
    "                    elif left == mid < right:\n",
    "                        res += count[keys[left]] * (count[keys[mid]] - 1) / 2 * count[keys[right]]\n",
    "                    elif left < mid == right:\n",
    "                        res += count[keys[left]] * count[keys[mid]] * (count[keys[right]] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        res += count[keys[left]] * (count[keys[mid]] - 1) * (count[keys[right]] - 2) / 6\n",
    "                    # print(keys[left], keys[mid], keys[right])\n",
    "                    right -= 1\n",
    "                    mid += 1\n",
    "\n",
    "                if cur_sum > target:\n",
    "                    right -= 1\n",
    "\n",
    "                if cur_sum < target:\n",
    "                    mid += 1\n",
    "\n",
    "        return int(res % mod)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        c = Counter(arr)\n",
    "        hashSet = set()\n",
    "        res = 0\n",
    "        for i in c:\n",
    "            for j in c:\n",
    "                k = target -i -j\n",
    "                if k in c:\n",
    "                    if \" \".join([str(s) for s in sorted([i,j,k])]) in hashSet:\n",
    "                        continue\n",
    "                    if i == j == k and c[i] >=3:\n",
    "                        res += math.comb(c[i], 3)\n",
    "                    elif i == j != k and c[i] >= 2:\n",
    "                        res += math.comb(c[i], 2) * c[k]\n",
    "                    elif i == k != j and c[i] >= 2:\n",
    "                        res += math.comb(c[i], 2) * c[j]\n",
    "                    elif j == k != i and c[j] >= 2:\n",
    "                        res += math.comb(c[j], 2) * c[i]\n",
    "                    elif i != j != k:\n",
    "                        res += c[i] * c[j] * c[k]\n",
    "                    res %= 10 ** 9 + 7\n",
    "                    hashSet.add(\" \".join([str(s) for s in sorted([i,j,k])]))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        print(count)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        cnt = Counter()\n",
    "        for i in arr:\n",
    "            cnt[i]+=1\n",
    "        mod = 1000000007\n",
    "        res = 0\n",
    "        for i in range(1, target):\n",
    "            for j in range(i):\n",
    "                if target-j-i<=i:\n",
    "                    break\n",
    "                res+=cnt[j]*cnt[i]*cnt[target-i-j]\n",
    "                res%=mod\n",
    "                print(i, j, target-i-j, res)\n",
    "        for i in range(target//2+1):\n",
    "            if cnt[i]<2:\n",
    "                continue\n",
    "            if target == 3*i:\n",
    "                res+=cnt[i]*(cnt[i]-1)*(cnt[i]-2)//6 if cnt[i]>=3 else 0\n",
    "            else:\n",
    "                res+=(cnt[i]-1)*cnt[i]//2*cnt[target-2*i]\n",
    "            res = res%mod\n",
    "        \n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        m=len(arr)\n",
    "        tmdb=[]\n",
    "        B=dict()\n",
    "        for i in range(m):\n",
    "            if arr[i] not in B.keys():\n",
    "                B[arr[i]]=1\n",
    "                tmdb.append(arr[i])\n",
    "            else:\n",
    "                B[arr[i]]+=1\n",
    "        res=0\n",
    "        tmdnk=len(tmdb)\n",
    "        tmdb.sort()\n",
    "        # 3\n",
    "        if tmdnk>=1:\n",
    "            for each in tmdb:\n",
    "                if each*3==target and B[each]>=3:\n",
    "                    res+=B[each]*(B[each]-1)*(B[each]-2)//6\n",
    "            res=res%(10**9+7)\n",
    "        # 2\n",
    "        if tmdnk>=2:\n",
    "            for i in range(tmdnk):\n",
    "                for j in range(tmdnk):\n",
    "                    if tmdb[i]+2*tmdb[j]==target and B[tmdb[j]]>=2 and (tmdb[i]!=tmdb[j]):\n",
    "                        res+=B[tmdb[i]]*(B[tmdb[j]])*(B[tmdb[j]]-1)//2\n",
    "            res=res%(10**9+7)\n",
    "        # 1\n",
    "        if tmdnk>=3:\n",
    "            for i in range(tmdnk):\n",
    "                for j in range(i+1,tmdnk):\n",
    "                    if (target-tmdb[i]-tmdb[j] in tmdb) and target-tmdb[i]-tmdb[j] > tmdb[j] :\n",
    "                        print(target-tmdb[i]-tmdb[j],tmdb[j],tmdb[i])\n",
    "                        res+=B[tmdb[i]]*B[tmdb[j]]*B[target-tmdb[i]-tmdb[j]]\n",
    "            res=res%(10**9+7)\n",
    "        return res\n",
    "        \n",
    "\n",
    "\n",
    "                \n",
    "        \n",
    "\n",
    "        \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "from unittest import result\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr, target):\n",
    "        arr.sort()\n",
    "        cnt = 0\n",
    "        MOD = 10**9 + 7\n",
    "\n",
    "        for i in range(0, len(arr)):\n",
    "            left_p = i + 1\n",
    "            right_p = len(arr) - 1\n",
    "\n",
    "            while right_p > left_p:\n",
    "                if arr[i] + arr[left_p] + arr[right_p] == target: \n",
    "                    if arr[left_p] == arr[right_p]:\n",
    "                        cnt += (right_p - left_p) * (right_p - left_p + 1) / 2\n",
    "                        break\n",
    "                    else:\n",
    "                        l_c = 1\n",
    "                        r_c = 1\n",
    "                        while arr[left_p + 1] == arr[left_p]:\n",
    "                            l_c += 1\n",
    "                            left_p += 1\n",
    "                        \n",
    "                        while arr[right_p - 1] == arr[right_p]:\n",
    "                            r_c += 1\n",
    "                            right_p -= 1 \n",
    "                        \n",
    "                        cnt += l_c * r_c\n",
    "                        left_p += 1\n",
    "                        right_p -= 1\n",
    "                elif arr[i] + arr[left_p] + arr[right_p] > target:\n",
    "                    right_p -= 1\n",
    "                else:\n",
    "                    left_p += 1\n",
    "        \n",
    "        res = int(cnt) % MOD\n",
    "        return res\n",
    "            \n",
    "if __name__ == \"__main__\":\n",
    "    arr = [1,1,2,2,3,3,4,4,5,5]\n",
    "    target = 8\n",
    "    print(Solution().threeSumMulti(arr, target))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# -*- coding: utf-8 -*-\n",
    "from typing import List\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        # 固定住一个\n",
    "        ans = 0\n",
    "        a = 0 \n",
    "        \n",
    "        while a < len(arr)-2:\n",
    "            count_1 = 1\n",
    "            while a+1<len(arr) and arr[a]==arr[a+1]:\n",
    "                count_1 += 1\n",
    "                a += 1\n",
    "         \n",
    "       \n",
    "            b = a+1\n",
    "            c = len(arr)-1\n",
    "            count_2 = 0\n",
    "            count_3 = 0 \n",
    "            while b < c:\n",
    "                print(arr[a],arr[b],arr[c])\n",
    "                count_2 = max(1, count_2)\n",
    "                while b+1 < len(arr) and arr[b]==arr[b+1]:\n",
    "                    count_2 += 1\n",
    "                    b += 1\n",
    "              \n",
    "                if b>=c:\n",
    "                    break\n",
    "                count_3 = max(1, count_3)\n",
    "                while c > b + 1 and arr[c] == arr[c-1]:\n",
    "                    count_3 += 1\n",
    "                    c -= 1\n",
    "               \n",
    "\n",
    "                \n",
    "                if arr[a] + arr[b] + arr[c] == target:\n",
    "                    print(arr[a],arr[b],arr[c],count_1,count_2,count_3)\n",
    "                    ans += count_1*count_2*count_3\n",
    "                    ans %= 10**9 + 7\n",
    "                    b += 1\n",
    "                    c -= 1\n",
    "                    count_2 = 0\n",
    "                    count_3 = 0\n",
    "                elif arr[a] + arr[b] + arr[c] > target:\n",
    "                    c -= 1\n",
    "                    count_3 = 0\n",
    "                else:\n",
    "                    b += 1\n",
    "                    count_2 = 0\n",
    "            a += 1\n",
    "            \n",
    "        a=0\n",
    "        while a < len(arr):\n",
    "            count_1 = 1\n",
    "            while a+1<len(arr) and arr[a]==arr[a+1]:\n",
    "                count_1 += 1\n",
    "                a += 1\n",
    "         \n",
    "            if arr[a]+arr[a]+arr[a]==target:\n",
    "                #print(arr[a],count_1)\n",
    "                ans += count_1*(count_1-1)*(count_1-2)//6\n",
    "                ans %= 10**9 + 7\n",
    "            b = a+1\n",
    "            while b<len(arr):\n",
    "                count_2 = 1\n",
    "                while b < len(arr) - 1 and arr[b]==arr[b+1]:\n",
    "                    count_2 += 1\n",
    "                    b += 1\n",
    "                if arr[a]+arr[a]+arr[b]==target:\n",
    "                    #print(arr[a],arr[b],count_1,count_2)\n",
    "                    ans += count_1*(count_1-1)//2 *count_2 \n",
    "                    ans %= 10**9 + 7\n",
    "                if arr[a]+arr[b]+arr[b]==target:\n",
    "                    #print(arr[a],arr[b],count_1,count_2)\n",
    "                    ans += count_2*(count_2-1)//2 *count_1 \n",
    "                    ans %= 10**9 + 7\n",
    "                b+=1\n",
    "            a+=1\n",
    "                \n",
    "        return ans \n",
    "\n",
    "if __name__==\"__main__\":\n",
    "    ans = Solution().threeSumMulti([3,2,0,2],5)\n",
    "    print(ans)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        mm=10**9+7\n",
    "        m=len(arr)\n",
    "        tmdb=[]\n",
    "        B=dict()\n",
    "        for i in range(m):\n",
    "            if arr[i] not in B.keys():\n",
    "                B[arr[i]]=1\n",
    "                tmdb.append(arr[i])\n",
    "            else:\n",
    "                B[arr[i]]+=1\n",
    "        res=0\n",
    "        tmdnk=len(tmdb)\n",
    "        tmdb.sort()\n",
    "        print(B)\n",
    "        # 3\n",
    "        if tmdnk>=1:\n",
    "            for each in tmdb:\n",
    "                if each*3==target and B[each]>=3:\n",
    "                    res+=B[each]*(B[each]-1)*(B[each]-2)//6\n",
    "            res=res%mm\n",
    "            print(res)\n",
    "        # 2\n",
    "        if tmdnk>=2:\n",
    "            for i in range(tmdnk):\n",
    "                for j in range(tmdnk):\n",
    "                    if tmdb[i]+2*tmdb[j]==target and B[tmdb[j]]>=2 and (tmdb[i]!=tmdb[j]):\n",
    "                        print(tmdb[i],tmdb[j])\n",
    "                        res+=B[tmdb[i]]*(B[tmdb[j]])*(B[tmdb[j]]-1)//2\n",
    "            res=res%mm\n",
    "            print(res)\n",
    "        # 1\n",
    "        if tmdnk>=3:\n",
    "            for i in range(tmdnk):\n",
    "                for j in range(i+1,tmdnk):\n",
    "                    if (target-tmdb[i]-tmdb[j] in tmdb) and target-tmdb[i]-tmdb[j] > tmdb[j] :\n",
    "                        print(target-tmdb[i]-tmdb[j],tmdb[j],tmdb[i])\n",
    "                        res+=B[tmdb[i]]*B[tmdb[j]]*B[target-tmdb[i]-tmdb[j]]\n",
    "            res=res%mm\n",
    "            print(res)\n",
    "        return res\n",
    "        \n",
    "\n",
    "\n",
    "                \n",
    "        \n",
    "\n",
    "        \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        # M = 10**9 + 7\n",
    "        # ans = 0\n",
    "        # for i in range(len(arr)):\n",
    "        #     for j in range(i+1, len(arr)):\n",
    "        #         for k in range(j+1, len(arr)):\n",
    "        #             if arr[i] + arr[j] + arr[k] == target:\n",
    "        #                 ans += 1\n",
    "\n",
    "        # return ans % M\n",
    "        from collections import defaultdict\n",
    "        import bisect\n",
    "        M = 10 ** 9 + 7\n",
    "        ans = 0\n",
    "        dic = defaultdict(list)\n",
    "        for i in range(len(arr)):\n",
    "            for j in range(i+1, len(arr)):\n",
    "                dic[arr[i]+arr[j]].append(j)\n",
    "        for key in dic.keys():\n",
    "            dic[key] = sorted(dic[key])\n",
    "\n",
    "        for k in range(len(arr)):\n",
    "            if target - arr[k] in dic.keys():\n",
    "                # for index in dic[target - arr[k]]:\n",
    "                #     ans += 1 if k > index else 0\n",
    "                ans += bisect.bisect_left(dic[target-arr[k]], k)\n",
    "\n",
    "        return ans % M"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "#         cnt = Counter(arr)\n",
    "#         arr.sort()\n",
    "#         n = len(arr)\n",
    "#         mod = 10**9+7       \n",
    "#         ans = 0\n",
    "#         for i in range(n-2):\n",
    "#             cnt[arr[i]] -= 1\n",
    "#             g = cnt.copy()\n",
    "#             for j in range(i+1,n-1):\n",
    "#                 # print(g,cnt)\n",
    "#                 g[arr[j]] -= 1\n",
    "#                 t = target - arr[i] - arr[j]\n",
    "#                 if t < arr[0]:\n",
    "#                     break\n",
    "#                 ans += g[t]%mod\n",
    "#         return ans%mod\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        mod = 10**9+7 \n",
    "\n",
    "        @lru_cache(None)\n",
    "        def dfs(i,t,c):\n",
    "            if c == 0:\n",
    "                return t == 0\n",
    "            if i >= n or t < arr[i]:\n",
    "                return 0          \n",
    "            return (dfs(i+1,t-arr[i],c-1) + dfs(i+1,t,c))%mod      \n",
    "        return dfs(0,target,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# class Solution:\n",
    "#     def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "#         cnt = Counter(arr)\n",
    "#         arr.sort()\n",
    "#         n = len(arr)\n",
    "#         mod = 10**9+7       \n",
    "#         ans = 0\n",
    "#         for i in range(n-2):\n",
    "#             cnt[arr[i]] -= 1\n",
    "#             g = cnt.copy()\n",
    "#             for j in range(i+1,n-1):\n",
    "#                 # print(g,cnt)\n",
    "#                 g[arr[j]] -= 1\n",
    "#                 t = target - arr[i] - arr[j]\n",
    "#                 if t < arr[0]:\n",
    "#                     break\n",
    "#                 ans += g[t]%mod\n",
    "#         return ans%mod\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        mod = 10**9+7 \n",
    "\n",
    "        @lru_cache(None)\n",
    "        def dfs(i,t,c):\n",
    "            # print(i,t,c)\n",
    "            if c == 0:\n",
    "                # print(t)\n",
    "                return t == 0\n",
    "            if i >= n or t < arr[i]:\n",
    "                return 0\n",
    "            \n",
    "\n",
    "            return (dfs(i+1,t-arr[i],c-1) + dfs(i+1,t,c))%mod\n",
    "            \n",
    "        \n",
    "        return dfs(0,target,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    \"\"\"\n",
    "    [-1, 0, 1, 2, -1, -4]\n",
    "    \n",
    "    [-4, -1, -1, 0, 1, 2]\n",
    "             i\n",
    "                lo\n",
    "                       hi\n",
    "    \n",
    "    \"\"\"\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        self.res = []\n",
    "        for i in range(len(nums)-2):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            if i == 0 or nums[i-1] != nums[i]:\n",
    "                self.twoSumII(nums, i)\n",
    "        return self.res\n",
    "            \n",
    "    def twoSumII(self, nums: List[int], i: int) -> List[List[int]]:\n",
    "        lo, hi = i+1, len(nums)-1\n",
    "        while lo < hi:\n",
    "            SUM = nums[lo] + nums[hi]\n",
    "            if SUM + nums[i] == 0:\n",
    "                self.res.append([nums[i], nums[lo], nums[hi]])\n",
    "                lo += 1\n",
    "                hi -= 1\n",
    "                while lo < hi and nums[lo] == nums[lo - 1]:\n",
    "                    lo += 1\n",
    "            elif SUM + nums[i] < 0:\n",
    "                lo += 1\n",
    "            else:\n",
    "                hi -= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "\n",
    "        res = []\n",
    "        nums.sort()\n",
    "\n",
    "        if nums[0] == nums[-1] == 0:    # special case, otherwise return [] for [0, 0, 0]\n",
    "            return [[0, 0, 0]]\n",
    "\n",
    "        for i in range(len(nums) - 2):  # iterate for the first number\n",
    "            if nums[i] > 0:             # unnecessary to check if least number sis positive\n",
    "                break\n",
    "            if nums[i] == nums[i-1]:    # avoiding duplication\n",
    "                continue\n",
    "            \n",
    "            l, r = i + 1, len(nums) - 1 # rest 2 numbers start from far edges of afterward\n",
    "\n",
    "            while l < r:\n",
    "                s = nums[i] + nums[l] + nums[r]\n",
    "                if s < 0:               # if neg, increase the smaller one\n",
    "                    l += 1\n",
    "                elif s > 0:             # if pos, decrease the greater one\n",
    "                    r -= 1\n",
    "                if s == 0:              # check, append and reduce duplication\n",
    "                    res.append((nums[i], nums[l], nums[r]))\n",
    "                    while l < r and nums[l] == nums[l + 1]:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == nums[r - 1]:\n",
    "                        r -= 1\n",
    "                    l += 1              # see if other pairs check.\n",
    "                    r -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        nums.sort()\n",
    "        Sum = []\n",
    "        for i in range(len(nums)-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "\n",
    "            s, e = i+1, len(nums)-1\n",
    "            while s < e:\n",
    "                if (nums[i]+nums[s]+nums[e]) == 0:\n",
    "                    Sum.append([nums[i], nums[s], nums[e]])\n",
    "                    while s < e and nums[s] == nums[s+1]:\n",
    "                        s = s+1\n",
    "                    while s < e and nums[e] == nums[e-1]:\n",
    "                        e -= 1\n",
    "                    s +=1\n",
    "                    e -= 1\n",
    "                elif (nums[s]+nums[e]+nums[i]) < 0:\n",
    "                    s += 1\n",
    "                else:\n",
    "                    e -= 1\n",
    "                    \n",
    "        return Sum\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        res = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            l = i+1\n",
    "            r = len(nums) - 1\n",
    "            while l < r:\n",
    "                s = nums[i]+nums[l]+nums[r]\n",
    "                if s > 0:\n",
    "                    r -= 1\n",
    "                elif s < 0:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    res.append((nums[i],nums[l],nums[r]))\n",
    "                    while l < r and nums[l] == nums[l+1]:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == nums[r-1]:\n",
    "                        r -= 1\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "        return list(set(res));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSum(self, nums):\n",
    "        nums.sort()\n",
    "        result = []\n",
    "        n = len(nums)\n",
    "        for i in range(n):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            head = i + 1\n",
    "            end = n - 1\n",
    "            while head < end:\n",
    "                if nums[i] + nums[head] + nums[end] == 0:\n",
    "                    result.append([nums[i], nums[head], nums[end]])\n",
    "                    head += 1\n",
    "                    while head < end and nums[head] == nums[head-1]:\n",
    "                        head += 1\n",
    "                    end -= 1\n",
    "                    while head < end and nums[end] == nums[end+1]:\n",
    "                        end -= 1\n",
    "                elif nums[i] + nums[head] + nums[end] < 0:\n",
    "                    head += 1\n",
    "                    while head < end and nums[head] == nums[head-1]:\n",
    "                        head += 1\n",
    "                else:\n",
    "                    end -= 1\n",
    "                    while head < end and nums[end] == nums[end+1]:\n",
    "                        end -= 1\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: 'List[int]') -> 'List[List[int]]':\n",
    "        def search_2sum(nums, target):\n",
    "            n = len(nums)\n",
    "            i, j = 0, n - 1\n",
    "            ret = []\n",
    "            while i < j:\n",
    "                if nums[i] + nums[j] == target:\n",
    "                    ret.append([nums[i], nums[j], -target])\n",
    "                    i, j = i + 1, j - 1\n",
    "                    while i < j and nums[i - 1] == nums[i]:\n",
    "                        i += 1\n",
    "                    while i < j and nums[j + 1] == nums[j]:\n",
    "                        j -= 1\n",
    "                elif nums[i] + nums[j] < target:\n",
    "                    l, r = i, j - 1\n",
    "                    while l <= r:\n",
    "                        c = (l + r) // 2\n",
    "                        if nums[c] + nums[j] == target:\n",
    "                            l = c\n",
    "                            break\n",
    "                        elif nums[c] + nums[j] < target:\n",
    "                            l = c + 1\n",
    "                        else:\n",
    "                            r = c - 1\n",
    "                    i = l\n",
    "                else:\n",
    "                    l, r = i + 1, j\n",
    "                    while l <= r:\n",
    "                        c = (l + r) // 2\n",
    "                        if nums[i] + nums[c] == target:\n",
    "                            r = c\n",
    "                            break\n",
    "                        elif nums[i] + nums[c] < target:\n",
    "                            l = c + 1\n",
    "                        else:\n",
    "                            r = c - 1\n",
    "                    j = r\n",
    "            return ret\n",
    "\n",
    "        nums = sorted(nums)\n",
    "        ret = []\n",
    "        for i in range(0, len(nums)):\n",
    "            ret.extend(search_2sum(nums[:i], -nums[i]))\n",
    "\n",
    "        ret = sorted(ret)\n",
    "        i = 0\n",
    "        for j in range(len(ret)):\n",
    "            if j and ret[j] == ret[j - 1]:\n",
    "                pass\n",
    "            else:\n",
    "                ret[i] = ret[j]\n",
    "                i += 1\n",
    "\n",
    "        # print(ret[:i])\n",
    "        return ret[:i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\tdef threeSum(self, nums):\n",
    "\t\t\"\"\"\n",
    "\t\t:type nums: List[int]\n",
    "\t\t:rtype: List[List[int]]\n",
    "\t\t\"\"\"\n",
    "\n",
    "\t\tresult = []\n",
    "\n",
    "\t\t# statistics appearance counts of the numbers in nums\n",
    "\t\tcount_dict = {}\n",
    "\t\tfor n in nums:\n",
    "\t\t\tcount_dict[n] = count_dict.get(n, 0) + 1\n",
    "\n",
    "\t\t# if 0 appears more than 2 times in nums\n",
    "\t\tif count_dict.get(0, 0) > 2:\n",
    "\t\t\tresult.append([0, 0, 0])\n",
    "\n",
    "\t\tnegatives = [n for n in count_dict.keys() if n < 0]\n",
    "\t\tpositives = [n for n in count_dict.keys() if n > 0]\n",
    "\n",
    "\t\tfor n in negatives:\n",
    "\t\t\tfor p in positives:\n",
    "\t\t\t\tneed = - (n + p)\n",
    "\t\t\t\tif need == n and count_dict[n] > 1:\n",
    "\t\t\t\t\tresult.append([n, n, p])\n",
    "\t\t\t\telif need == p and count_dict[p] > 1:\n",
    "\t\t\t\t\tresult.append([n, p, p])\n",
    "\t\t\t\telif n < need < p and need in count_dict:\n",
    "\t\t\t\t\tresult.append([n, need, p])\n",
    "\t\treturn result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "\n",
    "    def __init__(self):\n",
    "        self.result = []\n",
    "\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        cp = sorted(list(nums))\n",
    "        # print(cp)\n",
    "        i = 0\n",
    "        while i < len(cp) - 2:\n",
    "            if i > 0 and cp[i] == cp[i-1]:\n",
    "                i += 1\n",
    "                continue\n",
    "            temp = []\n",
    "            self.twoSum(cp[i+1:], temp, -cp[i])\n",
    "            for e in temp:\n",
    "                e.append(cp[i])\n",
    "                # print(cp[i])\n",
    "                # print(e)\n",
    "                # print()\n",
    "            self.result = self.result + temp\n",
    "            i += 1\n",
    "        # print(self.result)\n",
    "        return self.result\n",
    "\n",
    "\n",
    "    def twoSum(self, nums, result, target):\n",
    "        left = 0\n",
    "        right = len(nums) - 1\n",
    "        while left < right:\n",
    "            s = nums[left] + nums[right]\n",
    "            if s < target:\n",
    "                left += 1\n",
    "            elif s > target:\n",
    "                right -= 1\n",
    "            else:\n",
    "                result.append([nums[left], nums[right]])\n",
    "                while left < right and nums[left] == nums[left + 1]:\n",
    "                    left += 1\n",
    "                while left < right and nums[right] == nums[right - 1]:\n",
    "                    right -= 1\n",
    "                left += 1\n",
    "                right -= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "\n",
    "        nums = sorted(nums)\n",
    "\n",
    "        dicts = {}\n",
    "        for i, item in enumerate(nums):\n",
    "            dicts[item] = i\n",
    "        outs = []\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i + 1, len(nums)):\n",
    "                a = nums[i]\n",
    "                b = nums[j]\n",
    "                if -(a + b) in dicts.keys() and dicts[-(a + b)] > j and [a, b, -a - b] not in outs:\n",
    "                    outs.append([a, b, -a - b])\n",
    "        return outs\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#\r\n",
    "# @lc app=leetcode.cn id=15 lang=python3\r\n",
    "#\r\n",
    "# [15] 三数之和\r\n",
    "#\r\n",
    "# https://leetcode-cn.com/problems/3sum/description/\r\n",
    "#\r\n",
    "# algorithms\r\n",
    "# Medium (20.97%)\r\n",
    "# Total Accepted:    38K\r\n",
    "# Total Submissions: 181K\r\n",
    "# Testcase Example:  '[-1,0,1,2,-1,-4]'\r\n",
    "#\r\n",
    "# 给定一个包含 n 个整数的数组 nums，判断 nums 中是否存在三个元素 a，b，c ，使得 a + b + c = 0\r\n",
    "# ？找出所有满足条件且不重复的三元组。\r\n",
    "# \r\n",
    "# 注意：答案中不可以包含重复的三元组。\r\n",
    "# \r\n",
    "# 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]，\r\n",
    "# \r\n",
    "# 满足要求的三元组集合为：\r\n",
    "# [\r\n",
    "# ⁠ [-1, 0, 1],\r\n",
    "# ⁠ [-1, -1, 2]\r\n",
    "# ]\r\n",
    "# \r\n",
    "# \r\n",
    "#\r\n",
    "class Solution:\r\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\r\n",
    "        nums = sorted(nums)\r\n",
    "        l = len(nums)\r\n",
    "        r = set()\r\n",
    "        for c in range(l):\r\n",
    "            a = c+1\r\n",
    "            b = l-1\r\n",
    "            sum = -nums[c]\r\n",
    "\r\n",
    "            while a < b:\r\n",
    "                if nums[a] + nums[b] > sum:\r\n",
    "                    b -= 1\r\n",
    "                elif nums[a] + nums[b] < sum:\r\n",
    "                    a += 1\r\n",
    "                else:\r\n",
    "                    r.add(tuple(sorted([nums[a],nums[b],nums[c]])))\r\n",
    "                    a += 1\r\n",
    "                    b -= 1\r\n",
    "\r\n",
    "        return [list(t) for t in r]\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "        \r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        \"\"\"\n",
    "        对于 a + b + c = 0 共有四种可能的结果\n",
    "        [0 0 0] [- + +] [- - +] [- 0 +]\n",
    "        \"\"\"\n",
    "#         ans = []  # 初始化结果\n",
    "#         d = {}  # 重构nums,key=num,value=该值的个数\n",
    "        \n",
    "#         for i in nums:\n",
    "#             if i not in d:\n",
    "#                 d[i] = 0  # 将i存入d的key中\n",
    "#             d[i] += 1\n",
    "        \n",
    "#         posit = [a for a in d if a>0]\n",
    "#         naga = [b for b in d if b<0]\n",
    "        \n",
    "        \n",
    "        \n",
    "#         # [0 0 0]\n",
    "#         if d.get(0,0)>2:\n",
    "#             ans.append([0,0,0])\n",
    "        \n",
    "#         if not posit or not naga:\n",
    "#             return ans\n",
    "        \n",
    "#         # [- + +]\n",
    "#         for a,v in enumerate(posit):\n",
    "#             if d[v]>1 and -2*v in d:\n",
    "#                 ans.append([v,v,-2*v])\n",
    "#             else:\n",
    "#                 for b in posit[a+1:]:\n",
    "#                     if 0-v-b in d:\n",
    "#                         ans.append([v,b,0-v-b])\n",
    "        \n",
    "#         # [+ - -]\n",
    "#         for a,v in enumerate(naga):\n",
    "#             if d[v]>1 and -2*v in d:\n",
    "#                 ans.append([v,v,-2*v])\n",
    "#             else:\n",
    "#                 for b in naga[a+1:]:\n",
    "#                     if 0-v-b in d:\n",
    "#                         ans.append([v,b,0-v-b])\n",
    "        \n",
    "#         # [- 0 +]\n",
    "#         if 0 in d:\n",
    "#             for a in posit:\n",
    "#                 if -a in d:\n",
    "#                     ans.append([a,-a,0])\n",
    "#         return ans\n",
    "        ans = []\n",
    "        d = {}\n",
    "        for i in nums:\n",
    "            if i not in d:\n",
    "                d[i] = 0\n",
    "            d[i] += 1\n",
    "        zhengshu = [i for i in d if i > 0]\n",
    "        fushu = [i for i in d if i < 0]\n",
    "        \n",
    "        if d.get(0,0) > 2:\n",
    "            ans.append([0,0,0])\n",
    "        if zhengshu == [] or fushu == []:\n",
    "            return ans\n",
    "        \n",
    "        for i,x in enumerate(zhengshu):\n",
    "            if d[x] >= 2 and -2*x in d:\n",
    "                ans.append([x,x,-2*x])\n",
    "            for y in zhengshu[i+1:]:\n",
    "                if -(x+y) in d:\n",
    "                    ans.append([x,y,-x-y])\n",
    "        \n",
    "        for i,x in enumerate(fushu):\n",
    "            if d[x] >= 2 and -2*x in d:\n",
    "                ans.append([x,x,-2*x])\n",
    "            for y in fushu[i+1:]:\n",
    "                if -(x+y) in d:\n",
    "                    ans.append([x,y,-x-y])\n",
    "                    \n",
    "        if 0 in d:\n",
    "            for x in zhengshu:\n",
    "                if -x in d:\n",
    "                    ans.append([-x,0,x])\n",
    "                    \n",
    "        return ans\n",
    "\n",
    "            \n",
    "        \n",
    "                        \n",
    "                        \n",
    "                        \n",
    "                        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        d = {}\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        nums = sorted(nums)\n",
    "        for i , number in enumerate(nums):\n",
    "            j = i + 1\n",
    "            l = len(nums) - 1 \n",
    "            while j < l:\n",
    "                sum = nums[i] + nums[j] + nums[l]\n",
    "                if sum > 0:\n",
    "                    l = l - 1\n",
    "                elif sum < 0 :\n",
    "                    j = j + 1\n",
    "                else:\n",
    "                    t =  (nums[i],nums[j],nums[l])\n",
    "                    if t not in d:\n",
    "                        d[t] = 1\n",
    "                    if nums[j]==nums[l]:\n",
    "                        break\n",
    "                    l = l - 1\n",
    "                    j = j + 1\n",
    "                    \n",
    "        return [*map(list,d.keys()) ]\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "\n",
    "    def __init__(self):\n",
    "        self.result = []\n",
    "\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        cp = sorted(list(nums))\n",
    "        # print(cp)\n",
    "        for i in range(len(cp) - 2):\n",
    "            # print(cp[i])\n",
    "            # print(cp[i+1:])\n",
    "            if i > 0 and cp[i] == cp[i-1]:\n",
    "                continue\n",
    "            temp = []\n",
    "            self.twoSum(cp[i+1:], temp, -cp[i])\n",
    "            for e in temp:\n",
    "                e.append(cp[i])\n",
    "            self.result = self.result + temp\n",
    "\n",
    "        return self.getResult()\n",
    "\n",
    "\n",
    "    def twoSum(self, nums, result, target):\n",
    "        left = 0\n",
    "        right = len(nums) - 1\n",
    "        while left < right:\n",
    "            s = nums[left] + nums[right]\n",
    "            if s < target:\n",
    "                left += 1\n",
    "            elif s > target:\n",
    "                right -= 1\n",
    "            else:\n",
    "                result.append([nums[left], nums[right]])\n",
    "                left += 1\n",
    "                right -= 1\n",
    "\n",
    "\n",
    "    def getResult(self):\n",
    "        ret = self.result\n",
    "        threeret = set()\n",
    "        rrr = []\n",
    "        for r in ret:\n",
    "            h = \"\".join(map(lambda x: str(x), r))\n",
    "            if not h in threeret:\n",
    "                rrr.append(r)\n",
    "                threeret.add(h)\n",
    "        return rrr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        ans = []\n",
    "        nums.sort()\n",
    "        temp = nums[0] - 1\n",
    "        for i in range(len(nums) - 2):\n",
    "            if nums[i] == temp:\n",
    "                continue\n",
    "            else:\n",
    "                temp = nums[i]\n",
    "            left = 0\n",
    "            right = len(nums) - 1\n",
    "            while left < right:\n",
    "                if left == i:\n",
    "                    left += 1\n",
    "                    continue\n",
    "                if right == i:\n",
    "                    right -= 1\n",
    "                    continue\n",
    "\n",
    "                if nums[left] + nums[right] + nums[i] < 0:\n",
    "                    left += 1\n",
    "                elif nums[left] + nums[right] + nums[i] > 0:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    list_each = [nums[left], nums[right], nums[i]]\n",
    "                    list_each.sort()\n",
    "                    ans.append(list_each)\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        ans.sort()\n",
    "        import itertools\n",
    "        it = itertools.groupby(ans)\n",
    "        result_list = []\n",
    "        for g, k in it:\n",
    "            result_list.append(g)\n",
    "        return result_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: 'List[int]') -> 'List[List[int]]':\n",
    "        dic={}\n",
    "        triple=[]\n",
    "        for i in nums:\n",
    "            if i in dic:\n",
    "                dic[i] += 1\n",
    "            else:\n",
    "                dic[i] = 1\n",
    "\n",
    "        pos = [i for i in dic if i>0]\n",
    "        neg = [i for i in dic if i<0]\n",
    "        if 0 in dic and dic[0]>2:\n",
    "            triple.append([0,0,0])\n",
    "        for i in neg:\n",
    "            for j in pos:\n",
    "                want=-i-j\n",
    "                if want in dic:\n",
    "                    if (want==i or want==j) and dic[want]>1:\n",
    "                        triple.append([i,want,j])\n",
    "                    elif i<want<j:\n",
    "                        triple.append([i,want,j])\n",
    "        return triple\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "\n",
    "        results = []\n",
    "        nums_dict = {}\n",
    "        neg_nums = []\n",
    "        pos_nums = []\n",
    "        for num in nums:\n",
    "            if num in nums_dict:\n",
    "                nums_dict[num] += 1\n",
    "            else:\n",
    "                nums_dict[num] = 1\n",
    "                if num < 0:\n",
    "                    neg_nums.append(num)\n",
    "                else:\n",
    "                    pos_nums.append(num)\n",
    "\n",
    "        if 0 in nums_dict and nums_dict[0] >= 3:\n",
    "            results.append([0,0,0])\n",
    "\n",
    "\n",
    "        neg_nums = sorted(neg_nums)\n",
    "        pos_nums = sorted(pos_nums)\n",
    "\n",
    "        for first_num in neg_nums:\n",
    "            for sec_num in pos_nums:\n",
    "                rest_part = 0 - first_num - sec_num\n",
    "                if rest_part in nums_dict:\n",
    "                    if rest_part in (first_num, sec_num) and nums_dict[rest_part] >= 2:\n",
    "                        results.append([first_num, sec_num, rest_part])\n",
    "                    if  rest_part < first_num  or rest_part > sec_num:\n",
    "                        results.append([first_num, sec_num, rest_part])\n",
    "\n",
    "        return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        res = []\n",
    "        nums_dict = collections.Counter(nums)\n",
    "        if 0 in nums_dict and nums_dict[0] >= 3:\n",
    "            res.append([0, 0, 0])\n",
    "            \n",
    "        nums_set_list = list(set(nums))\n",
    "        nums_set_list.sort()\n",
    "        for i, num in enumerate(nums_set_list):\n",
    "            for j in nums_set_list[i+1:]:\n",
    "                if 2*j + num == 0 and nums_dict[j] >= 2:\n",
    "                    res.append([j, j, num])\n",
    "                if 2*num + j == 0 and nums_dict[num] >= 2:\n",
    "                    res.append([num, num, j])\n",
    "                dif = 0 - num - j\n",
    "                if dif > j and dif in nums_dict:\n",
    "                    res.append([num, j, dif])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # 整体思路与Java实现类似：先排序，再通过将三数之和转化成两数之和，循环数组判断；设置首尾指针，双向收缩\n",
    "    def threeSum(self, nums: 'List[int]') -> 'List[List[int]]':\n",
    "        result = []\n",
    "        # 若输入数组长度小于3，直接返回空result\n",
    "        if len(nums) < 3:\n",
    "            return result\n",
    "        # 对数组进行排序\n",
    "        nums.sort()\n",
    "        for i in range(0,len(nums) - 2):\n",
    "            num = -nums[i]\n",
    "            start = i + 1;\n",
    "            end = len(nums) - 1;\n",
    "            while(start < end):\n",
    "                if(nums[start] + nums[end] == num):\n",
    "                    lis = []\n",
    "                    lis.append(-num)\n",
    "                    lis.append(nums[start])\n",
    "                    lis.append(nums[end])\n",
    "                    # 检查结果数组有无重复\n",
    "                    if lis not in result:\n",
    "                        result.append(lis)\n",
    "                    start += 1\n",
    "                    end -= 1\n",
    "                # 进行判断，若小于num，首指针前进；反之，尾指针后退\n",
    "                elif(nums[start] + nums[end] < num):\n",
    "                    start += 1\n",
    "                else:\n",
    "                    end -= 1\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums):\n",
    "        res = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            l, r = i+1, len(nums)-1\n",
    "            while l < r:\n",
    "                s = nums[i] + nums[l] + nums[r]\n",
    "                if s < 0:\n",
    "                    l +=1 \n",
    "                elif s > 0:\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    res.append((nums[i], nums[l], nums[r]))\n",
    "                    while l < r and nums[l] == nums[l+1]:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == nums[r-1]:\n",
    "                        r -= 1\n",
    "                    l += 1; r -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "\n",
    "        #三指针遍历 三数之和\n",
    "        #先排序,再借助三个指针 k,i=k+1,j=len(num)-1 遍历判断\n",
    "        #判断准则：\n",
    "        # s = num[k]+num[i]+num[j]\n",
    "        # s < 0,则 i += 1;  s > 0，则 i -= 1; s==0，则arr.append\n",
    "        # 跳得的时候判断时候与前一次一样，一样的话继续跳\n",
    "        res = [] #记录 不重复的三元组\n",
    "        #先排序,再借助三个指针 遍历判断\n",
    "        nums.sort()\n",
    "        #\n",
    "        for k in range(len(nums)-2):\n",
    "\n",
    "            if nums[k] > 0:\n",
    "                break # 绝对大于0\n",
    "            #\n",
    "            if k>0 and nums[k] == nums[k-1]:\n",
    "                continue\n",
    "\n",
    "            i, j = k+1, len(nums) - 1\n",
    "            while i<j and j>0 and i<len(nums): #不重复\n",
    "                if nums[k] + nums[i] + nums[j] == 0:\n",
    "\n",
    "                    res.append([nums[k],nums[i],nums[j]])\n",
    "\n",
    "                    while  (i+1 < len(nums) - 1) and nums[i]==nums[i+1]: #避免重复，同时减少计算\n",
    "                        i = i + 1\n",
    "                    i = i + 1\n",
    "                    while j > 0 and nums[j]==nums[j-1]:\n",
    "                        j = j - 1\n",
    "                    j = j - 1\n",
    "                elif nums[k] + nums[i] + nums[j] < 0:\n",
    "                    while  (i+1 < len(nums) - 1) and nums[i]==nums[i+1]: #避免重复，同时减少计算\n",
    "                        i = i + 1\n",
    "                    i = i + 1\n",
    "                elif nums[k] + nums[i] + nums[j] > 0:\n",
    "                    while j > 0 and nums[j]==nums[j-1]:\n",
    "                        j = j - 1\n",
    "                    j = j - 1\n",
    "        #     while k+1 < len(nums) and nums[k] == nums[k+1]:\n",
    "        #         k = k + 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\r\n",
    "        if len(nums) < 3:\r\n",
    "            return []\r\n",
    "        nums = sorted(nums)\r\n",
    "        if (nums[0]+nums[1]+nums[2] > 0) or (nums[-1]+nums[-2]+nums[-3] < 0):\r\n",
    "            return []\r\n",
    "        res = []\r\n",
    "        for p1 in range(len(nums) - 2):\r\n",
    "            if nums[p1] + nums[p1 + 1] + nums[p1 + 2] > 0:\r\n",
    "                break\r\n",
    "            if p1 > 0 and nums[p1] == nums[p1 - 1]:\r\n",
    "                continue\r\n",
    "            p2, p3 = p1 + 1, len(nums) - 1\r\n",
    "            while p2 < p3:\r\n",
    "                tmp = nums[p1] + nums[p2] + nums[p3]\r\n",
    "                if tmp == 0:\r\n",
    "                    res.append([nums[p1], nums[p2], nums[p3]])\r\n",
    "                    p2 += 1\r\n",
    "                    p3 -= 1\r\n",
    "                elif tmp < 0:\r\n",
    "                    p2 += 1\r\n",
    "                else:\r\n",
    "                    p3 -= 1\r\n",
    "                while (p2 > p1 + 1) and (nums[p2] == nums[p2 - 1]) and (p2 < len(nums) - 1):\r\n",
    "                    p2 += 1\r\n",
    "                while (p3 < len(nums)-1) and (nums[p3] == nums[p3+1]) and (p3 > p1+1):\r\n",
    "                    p3 -= 1\r\n",
    "        return res\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        \n",
    "        if len(nums)<3:\n",
    "            return res\n",
    "\n",
    "        for i in range(0,len(nums)-2):\n",
    "            left = i+1\n",
    "            right = len(nums)-1\n",
    "            while left<=len(nums)-1 and right<=len(nums)-1 and left<right:\n",
    "                if nums[i]+nums[left]+nums[right]==0:\n",
    "                    temp_res = [nums[i],nums[left],nums[right]]\n",
    "                    if temp_res not in res:\n",
    "                        res.append(temp_res)\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif nums[i]+nums[left]+nums[right]<0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "            # print(res)\n",
    "\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        dataList = sorted(nums)\n",
    "        result = set([])\n",
    "        for index in range(len(dataList)-2):\n",
    "            index1 = index+1\n",
    "            index2 = len(dataList)-1\n",
    "            if dataList[index]>0:\n",
    "                break\n",
    "            if index>0 and dataList[index]==dataList[index-1]:\n",
    "                continue\n",
    "            while index1<index2:\n",
    "                sum_2 = dataList[index1]+dataList[index2]\n",
    "                if dataList[index]+dataList[index1]>0:\n",
    "                    break\n",
    "                if sum_2==-dataList[index]:\n",
    "                    result.add((dataList[index],dataList[index1],dataList[index2]))\n",
    "                    index1+=1\n",
    "                    index2-=1\n",
    "                elif sum_2>-dataList[index]:\n",
    "                    index2-=1\n",
    "                else:\n",
    "                    index1+=1\n",
    "        return list(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        for i in range(n):\n",
    "            left, right = i+1, n-1\n",
    "            while left < right:\n",
    "                sum_ = nums[i] + nums[left] + nums[right]\n",
    "                ans = [nums[i], nums[left], nums[right]]\n",
    "                if sum_ > 0:\n",
    "                    right -= 1\n",
    "                elif sum_ < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    if ans not in res:\n",
    "                        res.append(ans)\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        result = []\n",
    "        repeat = []\n",
    "        if len(nums) < 3:\n",
    "            return result\n",
    "        nums.sort()\n",
    "        while len(nums) > 2:\n",
    "            element = nums.pop()\n",
    "            if element in repeat:\n",
    "                continue\n",
    "            i, j = 0, len(nums) - 1\n",
    "            while i < j:\n",
    "                if nums[i] + nums[j] + element == 0:\n",
    "                    if [nums[i], nums[j], element] not in result:\n",
    "                        result.append([nums[i], nums[j], element])\n",
    "                    i += 1\n",
    "                    j -= 1\n",
    "                elif nums[i] + nums[j] + element > 0:\n",
    "                    j -= 1\n",
    "                elif nums[i] + nums[j] + element < 0:\n",
    "                    i += 1\n",
    "            repeat.append(element)\n",
    "        return result\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\r\n",
    "        nums.sort()\r\n",
    "        res = []\r\n",
    "        for idx, val in enumerate(nums):\r\n",
    "            # 特殊条件判断\r\n",
    "            if val > 0:\r\n",
    "                return res\r\n",
    "            if nums[idx] == nums[idx - 1] and idx > 0:\r\n",
    "                continue\r\n",
    "            left = idx + 1\r\n",
    "            right = len(nums) - 1\r\n",
    "            while left < right:\r\n",
    "                if val + nums[left] + nums[right] == 0:\r\n",
    "                    if [val, nums[left], nums[right]] not in res:\r\n",
    "                        res.append([val, nums[left], nums[right]])\r\n",
    "                    # 更新双指针\r\n",
    "                    left += 1\r\n",
    "                    right -= 1\r\n",
    "                elif val + nums[left] + nums[right] > 0:\r\n",
    "                    right -= 1\r\n",
    "                else:\r\n",
    "                    left += 1\r\n",
    "        return res\r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        ans = list()\n",
    "        \n",
    "        # 枚举 a\n",
    "        for first in range(n):\n",
    "            # 需要和上一次枚举的数不相同\n",
    "            if first > 0 and nums[first] == nums[first - 1]:\n",
    "                continue\n",
    "            # c 对应的指针初始指向数组的最右端\n",
    "            third = n - 1\n",
    "            target = -nums[first]\n",
    "            # 枚举 b\n",
    "            for second in range(first + 1, n):\n",
    "                # 需要和上一次枚举的数不相同\n",
    "                if second > first + 1 and nums[second] == nums[second - 1]:\n",
    "                    continue\n",
    "                # 需要保证 b 的指针在 c 的指针的左侧\n",
    "                while second < third and nums[second] + nums[third] > target:\n",
    "                    third -= 1\n",
    "                # 如果指针重合，随着 b 后续的增加\n",
    "                # 就不会有满足 a+b+c=0 并且 b<c 的 c 了，可以退出循环\n",
    "                if second == third:\n",
    "                    break\n",
    "                if nums[second] + nums[third] == target:\n",
    "                    ans.append([nums[first], nums[second], nums[third]])\n",
    "        \n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        start = 0\n",
    "        key = []\n",
    "        while start < len(nums):\n",
    "            second = start + 1\n",
    "            end = len(nums) - 1\n",
    "            while second < end and end < len(nums):\n",
    "                if nums[start] + nums[second] + nums[end] == 0:\n",
    "                    value = sorted([nums[start], nums[second], nums[end]])\n",
    "                    if value not in key:\n",
    "                        key.append(value)\n",
    "                    second += 1\n",
    "                elif nums[start] + nums[second] + nums[end] > 0:\n",
    "                    end -= 1\n",
    "                else:\n",
    "                     second += 1\n",
    "            start += 1\n",
    "        \n",
    "        return key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "\n",
    "        res = set()\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "\n",
    "            j, k = i + 1, len(nums)-1\n",
    "\n",
    "            while j < k:\n",
    "                if nums[i] + nums[j] + nums[k] == 0:\n",
    "                    res.add((nums[i], nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                elif nums[i] + nums[j] + nums[k] > 0:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    j += 1\n",
    "\n",
    "        return list(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        out = []\n",
    "        for i in range(0, len(nums) - 2):\n",
    "            L = i+1\n",
    "            R = len(nums) - 1\n",
    "            while (L < R):\n",
    "                if nums[i] + nums[L] + nums[R] == 0:\n",
    "                    if [nums[i], nums[L], nums[R]] in out:\n",
    "                        L += 1\n",
    "                        R -= 1\n",
    "                        continue\n",
    "                    out.append([nums[i], nums[L], nums[R]])\n",
    "                    L += 1\n",
    "                    R -= 1\n",
    "                elif nums[i] + nums[L] + nums[R] < 0:\n",
    "                    L += 1\n",
    "                elif nums[i] + nums[L] + nums[R] > 0:\n",
    "                    R -= 1\n",
    "        return out\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        result = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] > 0:\n",
    "                return result\n",
    "            if i > 0 and nums[i] == nums[i - 1]:\n",
    "                continue\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            while right > left:\n",
    "                n_sum = nums[i] + nums[left] + nums[right]\n",
    "                if n_sum > 0:\n",
    "                    right -= 1\n",
    "                elif n_sum < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    result.append([nums[i], nums[left], nums[right]])\n",
    "                    while right > left and nums[left] == nums[left + 1]:\n",
    "                        left += 1\n",
    "                    while right > left and nums[right] == nums[right - 1]:\n",
    "                        right -= 1\n",
    "                \n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        for i in range(len(nums)-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            m, n = i+1, len(nums)-1\n",
    "            while m < n:\n",
    "                if m > i+1 and nums[m] == nums[m-1]:\n",
    "                    m += 1\n",
    "                    continue\n",
    "                if n < len(nums)-1 and nums[n] == nums[n+1]:\n",
    "                    n -= 1\n",
    "                    continue\n",
    "                if nums[m] + nums[n] == -nums[i]:\n",
    "                    ans.append([nums[i], nums[m], nums[n]])\n",
    "                    m += 1\n",
    "                    n -= 1\n",
    "                    continue\n",
    "                if nums[m] + nums[n] < -nums[i]:\n",
    "                    m += 1\n",
    "                if nums[m] + nums[n] > -nums[i]:\n",
    "                    n -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        # 先将 nums 排序\n",
    "        nums.sort()\n",
    "        res, k = [], 0\n",
    "        for k in range(len(nums) - 2):\n",
    "            if nums[k] > 0:\n",
    "                break\n",
    "            # 跳过相同的nums[k]值\n",
    "            if k > 0 and nums[k] == nums[k-1]:\n",
    "                continue\n",
    "            i, j = k + 1, len(nums)-1\n",
    "            # 双指针\n",
    "            while i < j:\n",
    "                s = nums[k] + nums[i] + nums[j]\n",
    "                if s < 0:\n",
    "                    i += 1\n",
    "                    while i < j and nums[i] == nums[i-1]:\n",
    "                        i += 1\n",
    "                elif s > 0:\n",
    "                    j -= 1\n",
    "                    while i < j and nums[j] == nums[j+1]:\n",
    "                        j -= 1\n",
    "                else:\n",
    "                    res.append([nums[k], nums[i], nums[j]])\n",
    "                    i += 1\n",
    "                    j -= 1\n",
    "                    while i < j and nums[i] == nums[i-1]: i += 1\n",
    "                    while i < j and nums[j] == nums[j+1]: j -= 1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: list[int]) -> list[list[int]]:\n",
    "        nums.sort()\n",
    "        res = set()\n",
    "        n = len(nums)\n",
    "        for i in range(n-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            l = i + 1\n",
    "            r = n - 1\n",
    "            while l < r:\n",
    "                if nums[i] + nums[l] + nums[r] < 0:\n",
    "                    l += 1\n",
    "                elif nums[i] + nums[l] + nums[r] > 0:\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    res.add(tuple((nums[i], nums[l], nums[r])))\n",
    "                    while l < r and nums[l] == nums[l+1]:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == nums[r-1]:\n",
    "                        r -= 1\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "        return list(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        result = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums) - 2):\n",
    "            if nums[i] > 0 :\n",
    "                break\n",
    "            #i != j、i != k 且 j != k,需要去重\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            #双指针\n",
    "            left , right = i + 1, len(nums) - 1\n",
    "            while left < right:\n",
    "                total = nums[i] + nums[left] + nums[right]\n",
    "                if total < 0:\n",
    "                    left += 1\n",
    "                elif total > 0 :\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    result.append([nums[i],nums[left],nums[right]])\n",
    "                    while left < right and nums[left] == nums[left+1]:\n",
    "                        left+=1\n",
    "                    while left < right and  nums[right] == nums[right - 1]:\n",
    "                        right-=1\n",
    "                    left += 1\n",
    "                    right -=1\n",
    "        return result\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        result = set()\n",
    "        if n <= 2:\n",
    "            return []\n",
    "        for i in range(n-2):\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                if nums[left] + nums[right] + nums[i] == 0:\n",
    "                    result1 = [nums[left],nums[right],nums[i]]\n",
    "                    result1.sort()\n",
    "                    result1 = tuple(result1)\n",
    "                    result.add(result1)\n",
    "                    left +=1\n",
    "                    right -= 1\n",
    "                elif nums[left] + nums[right] + nums[i] < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return list(result) #慢"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = set()\n",
    "        for i in range(len(nums)-2):\n",
    "            if nums[i] > 0: break\n",
    "            l = i + 1\n",
    "            r = len(nums)-1\n",
    "            while l < r:\n",
    "                if nums[l]+nums[r]+nums[i] == 0:\n",
    "                    ans.add((nums[i],nums[l],nums[r]))\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                elif nums[i]+nums[l]+nums[r] < 0:\n",
    "                    l += 1\n",
    "                else: r -= 1\n",
    "        return list(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        res = []\n",
    "\n",
    "        n = len(nums)\n",
    "\n",
    "        nums.sort()\n",
    "\n",
    "        for i in range(n - 2):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            if nums[i] + nums[-1] + nums[-2] < 0:\n",
    "                continue\n",
    "            if i>0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            start = i + 1\n",
    "            end = n - 1\n",
    "            while start < end:\n",
    "                tmp = nums[start] + nums[end] + nums[i]\n",
    "                if tmp == 0:\n",
    "                    res.append([nums[i], nums[start], nums[end]])\n",
    "                    start += 1\n",
    "                    end -= 1\n",
    "                    while start < end and nums[end] == nums[end + 1]:\n",
    "                        end -= 1\n",
    "                    while start < end and nums[start] == nums[start - 1]:\n",
    "                        start += 1\n",
    "                elif tmp > 0:\n",
    "                    end -= 1\n",
    "                    while start < end and nums[end] == nums[end + 1]:\n",
    "                        end -= 1\n",
    "                else:\n",
    "                    start += 1\n",
    "                    while start < end and nums[start] == nums[start - 1]:\n",
    "                        start += 1\n",
    "\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res =[]\n",
    "        i = 0\n",
    "        for i in range(len(nums)):\n",
    "            if i == 0 or nums[i]>nums[i-1]:\n",
    "                l = i+1\n",
    "                r = len(nums)-1\n",
    "                while l < r:\n",
    "                    s = nums[i] + nums[l] +nums[r]\n",
    "                    if s ==0:\n",
    "                        res.append([nums[i],nums[l],nums[r]])\n",
    "                        l +=1\n",
    "                        r -=1\n",
    "                        while l < r and nums[l] == nums[l-1]:\n",
    "                            l += 1\n",
    "                        while r > l and nums[r] == nums[r+1]:\n",
    "                            r -= 1\n",
    "                    elif s>0:\n",
    "                        r -=1\n",
    "                    else :\n",
    "                        l +=1\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        def twoSum(nums, target):\n",
    "            res = []\n",
    "            dic = {}\n",
    "            use_set = set()\n",
    "            for i,num in enumerate(nums):\n",
    "                if num not in dic:\n",
    "                    dic[target-num] = num\n",
    "                elif num not in use_set:\n",
    "                    res.append([target-num, num])\n",
    "                    use_set.add(num)\n",
    "\n",
    "            return res\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        for i, n in enumerate(nums):\n",
    "            if i>0 and nums[i-1]==nums[i]:\n",
    "                continue\n",
    "            for twonum in twoSum(nums[i+1:], -n):\n",
    "                res.append([n]+twonum)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        ans = []\n",
    "        nums.sort()\n",
    "\n",
    "        import bisect\n",
    "        l = bisect.bisect_left(nums, 0)\n",
    "\n",
    "        import sys\n",
    "        temp_a  = sys.maxsize\n",
    "        temp_b = sys.maxsize\n",
    "\n",
    "        for index_a, i in enumerate(nums[:l]):\n",
    "            if temp_a == i:\n",
    "                continue\n",
    "            else:\n",
    "                temp_a = i\n",
    "            temp_b = sys.maxsize\n",
    "            for index_b, j in enumerate(nums[l:][::-1]):\n",
    "                if temp_b == j:\n",
    "                    continue\n",
    "                else:\n",
    "                    temp_b = j\n",
    "                t = bisect.bisect_left(nums, 0 - i - j)\n",
    "                if t < len(nums):\n",
    "                    if nums[t] == 0 - i - j:\n",
    "                        if i == 0 - i - j and j == 0 - i - j:\n",
    "                            if nums.count(0 - i - j) > 2:\n",
    "                                temp = sorted([i , j ,0 - i - j])\n",
    "                                if temp not in ans:\n",
    "                                    ans.append(temp)\n",
    "                        elif i == 0 - i - j:\n",
    "                            if nums.count(0 - i - j) > 1:\n",
    "                                temp = sorted([i , j ,0 - i - j])\n",
    "                                if temp not in ans:\n",
    "                                    ans.append(temp)\n",
    "                        elif j == 0 - i - j:\n",
    "                            if nums.count(0 - i - j) > 1:\n",
    "                                temp = sorted([i , j ,0 - i - j])\n",
    "                                if temp not in ans:\n",
    "                                    ans.append(temp)\n",
    "                        else:\n",
    "                            temp = sorted([i , j ,0 - i - j])\n",
    "                            if temp not in ans:\n",
    "                                ans.append(temp)\n",
    "                else:\n",
    "                    break\n",
    "       \n",
    "        if nums.count(0) > 2:\n",
    "            ans.append([0, 0, 0])\n",
    "\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
